Friday October 28, 2005 dL4 For Unix Runtime 6.1.4 Maintenance Release All Rights Reserved. Copyright (c) 1994 - 2005 by: Dynamic Concepts, Inc. Aliso Viejo, CA 92656 USA Email address: techsupport@dynamic.com Information: www.dynamic.com Downloads: ftp.dynamic.com Pre-installation instructions ============================= o This release requires an SSN authorized for release 6 of dL4. Without such an SSN, dL4 can only be used in single user demo mode. o Passport 4.1 or later must be installed in order to use release 6.1.4 of dL4. o Due to MySQL licensing requirements, the MySQL drivers cannot be used without a special SSN product option. Please contact the Dynamic Concepts Sales department for information on obtaining the required SSN. o Problem reports should be emailed to techsupport@dynamic.com. All problem reports should contain a description of the problem, the operating system name/revision, and, if at all possible, a reproducible sequence Highlights of This Release ========================== o A new utility, tools/makeuniv, has been added to convert UniBasic files to Universal files. o Mac OS X is a supported platform (A4). o When using dL4Term, JPEG, BMP, and other image files can be displayed in a window or to a printer. o Various enhancements have been to GUI programming when using dL4Term. Installation instructions ========================= 1. Ensure that you have Passport version 4.1 or greater installed on your system. For common platforms, the latest Passport software can be obtained from www.dynamic.com or ftp.dynamic.com. 2. Login as 'root'. 3. If upgrading an existing dL4 installation, make certain that all dL4 scope and run users have exited dL4. If a program cache is used (see the dL4 Installation and Configuration Guide), delete any existing cache using the Unix ipcs and ipcrm utilities. 4. Copy the distribution file to any temporary directory on your system, e.g. "/tmp". 5. If the distribution file has a ".Z" extension, uncompress the file using the command "uncompress filename.Z". If the file has an extension of ".z", rename the file with an uppercase "Z" before uncompressing the file. 6. Unpack the distribution file using the command "cpio -imcdu 2gb) format. makeuniv Utility to convert UniBasic files to Universal files. pgmcache Utility to display or delete the program cache. query Utility to display file characteristics. term Utility to monitor or terminate ports. verindex Utility to validate Portable or Universal Indexed-Contiguous files. oldcalls.lib A dL4 library that implements CALL DYNWIND() and CALL MONITOR(). Other utilities Other utilities including converted versions of many UniBasic utilities dL4 and dL4Term =============== o Some of the new features of dL4 6.1.4 are supported only when using dL4 with the dL4Term 6.1 telnet client. dL4Term is a separately available and licensed product. Please contact the Dynamic Concepts Sales department for information on obtaining a copy of dL4Term 6.1. New in This Release ================================================================================ Oct 28 2005 (Maintenance Release 6.1.4) o A new ARITHMETIC option, OPTION ARITHMETIC EXTENDED IEEE, has been added to map 1% and 7% to 16 bit and 32 bit signed binary integers instead of signed BCD integers. Using this option extends the range of 1% and 7% variables. This option uses IEEE floating point decimal formats for 2% thru 5% and, except for 1% and 7%, it is identical to the default numeric precision option of ARITHMETIC IEEE DECIMAL. o The performance of the MySQL driver has been improved when used with queries that produce large result sets. o Behavior change: when using dL4Term, DEL ("\177\") characters will be ignored when output instead of producing an error 5. o Bug fixed: CALL PROGRAMDUMP() would hang (enter an "infinite" loop) when displaying string variables with a large number of unprintable characters. CALL PROGRAMDUMP() also output only one truncated line for large string values instead of the expected multiple lines. Sep 14 2005 (Maintenance Release 6.1.3) o Passport 4.1 is required to run release 6.1.3 or later of dL4. o SCO OpenServer 6 is supported by platform 55 which has been renamed as "SCO OpenServer 6 / UnixWare 7". o Bug fixed: closing a FoxPro Full-ISAM file in a SWAPped program sometimes prevented accessing or closing other files. o Bug fixed: the TERM utility now assumes a 24 line screen if paging on a terminal that has a screen height of zero. Aug 12 2005 (Maintenance Release 6.1.2) o The MySQL SQL driver now supports reading TIME values into numeric or string variables. If read into a numeric variable, the time will be converted to seconds from midnight. o The MySQL SQL driver now supports reading TEXT values into string variables. o The MySQL SQL driver now supports reading backwards from the current position in the result set using record -3. o The MySQL SQL and MySQL Full-ISAM drivers now report the following new error codes when appropriate: 279 SQL implementation or configuration limit exceeded 280 SQL procedure error 281 Constraint not satisfied 282 Deadlock detected o Behavior change: the formatting of attachments in the email driver has been changed to improve compatibility with some email clients. o Behavior change: the scope DISPLAY command and CALL PROGRAMDUMP() now print quotation marks in string variables as two consecutive single quotes. This is the format used by the LIST command when printing string literal values in programs. o Bug fix: the BATCH utility did not work. Jun 17 2005 (Maintenance Release 6.1.1) o The MySQL Full-ISAM and MySQL SQL drivers now use the MySQL 4.1 client library to provide compatibility with MySQL 4.1 server passwords. Both drivers can also be used with earlier versions of the MySQL server. o The CHF$() and CHF#() functions have been implemented in the C-Tree driver to return information about the index portions of indexed contiguous files. This change is only important if the C-Tree portion is opened by itself (indexed contiguous files have always supported CHF$() and CHF#()). o A new command line option, "-noshell", has been added to scope. The option disables running non-dL4 programs from a SCOPE or BASIC command line. o Enhancement: CALL RDFHD() now supports file and directory names that contain spaces. o Enhancement: the terminal translation driver now supports large string parameters. o Bug fixed: CALL SORTINSTRING() sometimes caused memory violations. o Bug fixed: CALL RDFHD() sometimes reported a random error, usually "Illegal driver operation", when the creation date, access date, or file id parameter precision was too small to contain the returned value. o Bug fix: the debugger LET command did not work and reported a "format" error. Apr 20 2005 (Release 6.1) o A new intrinsic CALL, DRAWIMAGE(), has been added to display JPEG, BMP, and other image files in a window or to a printer. This feature can only be used with dL4Term. The new CALL has the following syntax: Call DrawImage(Filename$, X1, Y1, X2, Y2) or Call DrawImage(Channel, Filename$, X1, Y1, X2, Y2) where: "Filename$" is the path of an image file, "X1" and "Y1" are the horizontal and vertical coordinates of the upper left corner of the rectangle in which the image should be displayed, "X2" and "Y2" are the horizontal and vertical coordinates of the lower right corner of the rectangle in which the image should be displayed. The image will be displayed as large as possible within the display rectangle without changing the aspect ratio of the image. o Two new mnemonics, 'FITIMAGE' and 'FILLIMAGE', has been defined to draw client system JPEG, BMP, and other image files in a window or on a printer. This feature can only be used with dL4Term. The 'FITIMAGE' mnemonic draws an image as large as possible in a specified rectangle without changing the aspect ration of the image. The 'FILLIMAGE' mnemonic stretches or shrink the image as necessary to fill the entire specified rectangle. Examples: Print #1;PChr$("filepath",X1,Y1,X2,Y2);'FITIMAGE' Print #1;PChr$("filepath",X1,Y1,X2,Y2);'FILLIMAGE' where "X1" and "Y1" are the horizontal and vertical coordinates of the upper left corner of the display rectangle and "X2" and "Y2" are the coordinates of the lower right corner. The file path must specify a valid path on the client system running dL4Term. If the file does not exist on the client system, no error will occur and nothing will be displayed. o A new mnemonic, 'WCEXTKEYS', has been defined to enable extended key functionality in GUI programs. After printing the mnemonic 'WCEXTKEYS' to a dL4 or dL4Term window, pressing the ENTER key will cause the input focus to move from the current GUI element to the next GUI element with a tab stop defined (this is identical to the behavior of the TAB key). The 'WCEXTKEYS' mnemonic will also cause the ENTER key to generate a new line when typed in a subsequently created WCMEMO box. These two features can be enabled or disabled individually by using a numeric parameter to the 'WCEXTKEYS' mnemonic as shown below: 'WCEXTKEYS' - enables both ENTER-as-TAB-between-GUI-elements and ENTER-as-newline in WCMEMO box. '1WCEXTKEYS' - enables only ENTER-as-TAB-between-GUI-elements. '2WCEXTKEYS' - enables only ENTER-as-newline in WCMEMO box. '3WCEXTKEYS' - enables both features. '0WCEXTKEYS' - disables both features. o The 'WCTEXT' mnemonic now supports an eighth parameter to define the logical width of the text box and enable a horizontal scroll bar. This feature is used to display text which is wider than the text box. The following example defines a text box which is 40 character wide in the window, but contains up to 80 character wide lines. Print PChr$(10,5,20,9,60,"Label",2,80);'WCTEXT'; o The range of GUI element numbers has been increased to 1 through 9999. The previous range was 1 to 1000. o A "RAW" option has been implemented in the DEF STRUCT statement for structure members and for entire structures. This option can be used with structures so that READ RECORD and WRITE RECORD statements will use "Raw" file behavior when accessing contiguous files. This allows placing numeric fields on odd byte boundaries, writing entire strings as in MAT WRITE, and not including an extra character for string terminators (when a string is DIMmed as 10 characters, a normal READ or WRITE treats the field as being 11 characters long). Examples: Def Struct CUSTREC : Raw Member AString$[10] Member 3%,ANumber End Def Def Struct CUSTREC Member AString$[10] : Raw Member 3%,ANumber End Def o The bridge driver has been extended to allow use of random record numbers in SEARCH deallocate or insert operations if the "real record number" option is being used. o A "serialize" open option has been added to the text file driver to prevent multiple programs that are writing to the same text file from intermixing their output. This option would normally be used when appending to a log file. Example: Open #1,"(serialize)logfile.txt" Print #1;Tim#(0);": Process started" If multiple lines are being written, all lines must be written in a single statement or the lines may be intermixed. o The "TCP Socket" and "Socket Text" drivers now support an open option, "OPENTIME=n", to cause OPEN statements to timeout after "n" seconds. Example: Open #3,"(opentime=10)www.dynamic.com" As "Socket" o The driver for UniBasic Indexed-Contiguous files (non-portable and non-Universal) now supports greater-than-or-equal SEARCH statements. o The MySQL SQL driver now supports a "db=" option in the "DL4MYSQL" runtime/environment parameter. The "db=" option is equivalent to the "database=" option. o The MySQL Full-ISAM driver now supports a "db=" option in the "DL4MYSQLISAM" runtime/environment parameter. The "db=" option is equivalent to the "database=" option. o The MySQL Full-ISAM driver now supports a "readahead=n" open option where "n" is the number of rows to buffer when reading sequentially in read-only (ROPEN) mode. Reading backwards is not supported when "n" is greater than one. o The MySQL Full-ISAM driver now requires a MySQL server version of 4.0.3 or later for full functionality. o A new BUILD option has been added to the Portable and Universal indexed contiguous file drivers. The "key=l1:l2:.." option creates indexes at the same time the file is created. The option creates an index, starting with index 1, for each of the key length values l1, l2, through ln. The key lengths are specified in bytes. Example: Build #3,"(key=10,6,16)[1:40]filename" o A new SEARCH mode has been defined to search for the next allocated record in a Portable or Universal indexed contiguous file. The new mode is invoked by SEARCH mode 3 with an index value of 0. The statement will return the next allocated record number greater than the supplied record number. A key parameter is syntactically required by the SEARCH statement, but it is not used by the new mode. Example: Search #1,3,0;DummyKey$,RecNbr,Status o A new open option, "ARGS=value", has been added to the pipe driver to define an "ARGS" parameter to the driver selected by an "OPENAS=" option. o A new utility, tools/makeuniv, has been added to convert UniBasic files to Universal files. The makeuniv utility is an extended version of the ctool utility. The utility converts non-portable UniBasic formatted, contiguous, and indexed contiguous files to Universal or Portable equivalents. Conversion is normally performed in three steps: 1. The utility is used with the "-p" option is used to generate a prototype conversion file which lists all of the UniBasic files in the specified directory and its subdirectories. For BCD ("Q") data files, the prototype conversion file will be produced with all of the information needed to convert the files and no changes will be needed. For non-BCD files, the user must edit the conversion file and add record field definitions. Example: makeuniv -p ubfiles.txt datafile-directory 2. Edit the prototype conversion file to add any needed record field definitions and to check for warning messages. 3. The utility is executed again with the "-o" option and the conversion file created in steps 1 and 2. This step performs the actual conversion of the files in the source directory to Universal or Portable files in the destination directory. The utility will create the destination directory and any subdirectories if they do not already exist. Example: makeuniv -o newfile-directory ubfiles.txt Because non-Universal UniBasic files are not portable, the conversion must be performed on the same type of system on which the files were created. In addition, the file and directory names must not contain spaces. Command line syntax: makeuniv [-[klruU]] [-t arg] -o dir filename makeuniv [-l] [-[cfi] arg] [-t arg] -p filename sourcedir makeuniv -[h?] makeuniv -v The options and arguments have the following functions: -h or -? Output basic help. -H Output extended help. -v Output version number. -c arg Set contiguous and indexed contiguous file conversion options according to "arg". The only option is "allstring" which treats non-BCD file records as all string data. A record section will be output for non-BCD files defining the record as a single string. Manual editing of the record section will not be required. -f arg Set formatted file conversion options according to "arg". The option can either be "inttobcd" or or "extended". The "inttobcd" option converts 16-bit binary integer fields to BCD integers and may cause overflow errors during conversion. The "extended" option allows the use of binary integers and 5 word BCD floating point. An "extended" file can not be accessed by UniBasic. -i arg Set index conversion options according to "arg". The only option is "iriskeys" which converts IRIS or binary keys ("k" files) to ASCII strings. -k Use random key insertion algorithm. -l Use dL4 LUMAP and/or DL4LUST. -o dir Build destination files in directory "dir". -p filename Output conversion layout profile to "filename". -r Replace destination file. -t arg Select files according to "arg" which can be any combination of "b" (BCD files), "n" (non-BCD files), "c"(contiguous), "f" (formatted), and "i" (indexed contiguous). -u Enable "records-in-use" count (default setting). -U Disable "records-in-use" count. filename Conversion layout filename. sourcedir Source data file directory. Additional information on how to create file definitions in the conversion file can be found in the ctool manual or in dL4 6.1 Command Reference manual (when it is available). o dL4 is now available for use on systems running Mac OS X 10.3 or later. Please contact Dynamic Concepts for information on how to configure Mac OS X for use with dL4. o The intrinsic CALL DXMerge() can now support "include" files. Please see the dynamicXport documentation for additional information on CALL DXMerge(). o The tools/query utility has been enhanced with a "-k" option to count the number of keys used in indexed contiguous file directories. A "-s" option has been added to output Full-ISAM information in the form of DEF STRUCT and MEMBER statements. The "/" character can no longer be used as a lead-in for options. o The SCOPE debugger now supports the SPC(), MSC(), and HEX$() functions. In addition, debugger expressions can now use relational operators, logical operators, and concatenation. o Program dumps (as from CALL ProgramDump()) display MSC() values 44 through 46. o Bug fixed: potential memory corruption problems in the MySQL SQL driver, the SQLV$() function, the SQLN$() function, and the SQLNV$() function have been corrected. o Bug fixed: many of the standard terminal definition files did not draw lines or boxes correctly. o Bug fixed: the VT100 terminal definition file did not clear the state of the character attributes. o Bug fixed: the "printer/pcl.prf" printer definition file did not draw boxes correctly. o Bug fixed: when DL4DEFLU was defined but the directory specified in DL4DEFLU didn't exist, an error occurred when building new files. o Bug fixed: the "-c checksum" option of the tools/checksum utility did not work in MD5 mode if the checksum value had less than 32 digits. o Bug fixed: the "OPENAS=" open option in the pipe driver can now select the pipe driver itself as a driver. o Bug fixed: a potentially long table scan occurred for each sequential read in a non-unique index when using the MySQL Full-ISAM driver. Mar 7 2005 (Maintenance Release 5.3.6) o Bug fixed: FoxPro Full-ISAM memo fields did not work on Linux x86 systems and possibly some other platforms. o Bug fixed: the "-c checksum" option of the tools/checksum utility did not work in MD5 mode if the checksum value had less than 32 digits. Sep 28 2004 (Maintenance Release 5.3.5) o A new MSC() function, MSC(46), has been defined to return the original line number at which a CALL stack propagated error occurred. For example, if a "Divide by Zero" error occurred at line 150 of a procedure which did not have an error handler and the caller did have an error handler, SPC(10) would report the error as occurring at the CALL statement. The new MSC(46) function will report the original error line number of 150. o Bug fixed: when using dL4Term, a memory violation occurred if columns beyond the end of the line were selected and the DELETE key was pressed. o Bug fixed: empty string values in the SQLV$() and SQLNV$() functions caused random errors in the MySQL SQL driver. Aug 26 2004 (Maintenance Release 5.3.4) o The email driver has been enhanced to support user authentication on SMTP servers that require user authentication. To enable authentication, the OPEN statement option parameters or the DL4EMAILSERVER environment variable must specify the new "user" and "password" (or "pswd") options. These options must not be specified unless the SMTP server supports authentication. Examples: Open #5,"(user=fred,password=secret,from=fred)henry" As "Email" DL4EMAILSERVER="smtp.something.com,user=fred,password=secret" In addition to the new "user", "password", and "pswd" options, an additional "auth" option has been added to allow selection of a specific authorization method. The email driver currently supports the three most common methods: "LOGIN", "PLAIN", and "CRAM-MD5". The driver will use the best method available on the SMTP server with preference given to "CRAM-MD5" because it does not transmit the actual password over the network. The "auth" option can be used to select the "LOGIN" or "PLAIN" method if the SMTP server provides an incompatible "CRAM-MD5" method. If the "auth" option selects a method that is not supported by the SMTP server, the email driver will attempt to connect without authenticating the user. Example: DL4EMAILSERVER="smtp.something.com,auth=login" Note: for compatibility with previous releases, the DL4EMAILSERVER value, if defined, must begin with a server name. o Bug fixed: the SCOPE DISPLAY command and program dumps did not list string members of structure variables that had null ("") values. Jun 23 2004 (Maintenance Release 5.3.3) o Two new printer drivers, "Terminal Printer" and "Default Terminal Printer" have been added to open a named or the default printer via dL4Term on a client PC. o A new intrinsic CALL, UBSTRING(), and two new intrinsic functions, UBASC() and UBCHR$(), have been added to provide uniBasic-like character conversion routines. The parameters and return values of the routines are identical to CALL STRING(), ASC(), and CHR$() except that ASCII characters are mapped to the integer range 129 through 255 and uniBasic compatible mnemonics are mapped to the range 1 through 127. These routines can be used to simplify conversion of uniBasic programs to dL4. o Bug fixed: when upgrading dL4, an error occurred if "scope" or "run" were currently in use. o Bug fixed: the intrinsic CALLs UNPKDEC21(), UNPKDEC46(), UNPKRDX5019(), and UNPKRDX5049() copied random data into the destination variable after the unpacked data. o Bug fixed: Mode 4 of CALL STRING() did not add a string terminator after the converted character value. May 21 2004 (Maintenance Release 5.3.2) o A new open option, "CONTENT=HTML" has been added to the email driver to send email with HTML formatting commands. The driver enables HTML formatting, but it does not add formatting commands itself. The application is responsible for all HTML formatting commands as shown in the following example: Opts$ = "(From=someone,Content=html,Subject=''(test)'')" Open #1,Opts$ + "somebody" As "Email" Print #1;"This is bold and this is underlined." Close #1 The open option "CONTENT=TEXT" selects non-HTML text format (the default). o Bug fixed: percent sign ("%") and underscore ("_") characters were converted to "\%" and "\_" when adding data to or searching in MySQL tables using the MySQL driver or the MySQL Full-ISAM driver. May 7 2004 (Maintenance Release 5.3.1) o Bug fixed: CALL INPBUF() inserted typeahead characters at end of the typeahead buffer when used with dL4Term instead of at the beginning of the buffer as done for other terminal types. o Bug fixed: the Replace$() and ReplaceCI$() intrinsic string functions corrupted memory when replacing a single character with a multiple character string. Apr 14 2004 (Release 5.3) o A new option has been added to the Full-ISAM Bridge driver profile to support unbalanced indexes by allowing such indexes to be placed in separate Indexed-Contiguous or Full-ISAM files outside the main Full-ISAM file. For example, if index 3 of an Indexed-Contiguous file is used as a scratch index with entries for only some of the file records (and is thus unbalanced), that index could not be emulated by the Bridge driver within the main Full-ISAM file because Full-ISAM files do not support unbalanced indexes. Using the new option, the index can be emulated by declaring an external index in the bridge profile. For example: [Index3] File=filename Index=1 KeyPart=name,0,10 This example directs the bridge driver to perform all SEARCH operations on index 3 by applying the SEARCH operations to index 1 of the Indexed Contiguous file "filename". The bridge profile would also have to use the "RealRecordNumbers" option described below so that the record numbers in the keys of index 3 could be used to reference records in the main Full-ISAM file. External indexes can have multiple keys for the same record or use multiple key formats. The data in the key is completely controlled by the application and does not need to be present in any of the fields of the main Full-ISAM file. An external index definition can only have one "KeyPart" entry and, if the external index file is indexed contiguous, the field name is ignored (but it must be specified). External index files can either be Indexed Contiguous files or Full-ISAM files. If an Indexed-Contiguous file is used, the bridge driver will only access the index portion of the file. To use a Full-ISAM file as an external index file, the following format must be used in the bridge profile: [Index3] File=filename Name=indexname KeyPart=keyfieldname,0,10,,,Strip RecPart=recnbrfieldname where "filename" is the name of the external Full-ISAM file, "indexname" is the name of the index within the Full-ISAM file, "keyfieldname" is the name of the Full-ISAM field used for the key (this must be a character field), and "recnbrfieldname" is the name of the Full-ISAM field used for the record number (this must be a numeric field). External index definitions can include "Filename", "Protection", "Options", "OpenAs", and "OpenInProfileDirectory" entries using the same format and function as such entries in the main bridge profile section. If the file protection option is not specified, the protection options used to open the main Full-ISAM file will be applied when opening the external index file. o A new option has been added to the Full-ISAM Bridge driver profile to support programs reading records by record number. When set to TRUE, the option "RealRecordNumbers" causes the driver to return the actual Full-ISAM file record number when performing SEARCH statements that return a record number. The record numbers returned by SEARCH can then be used to perform random reads from the file. The option can only be used with Full-ISAM drivers and files that support searching index 0 for equal record numbers. Example: [FullISAMBridge] File=filename OpenAs=FoxPro Full-ISAM RealRecordNumbers=True o The Full-ISAM Bridge driver has been enhanced to support keys that contain the current record number when the Bridge driver is used with the MySQL Full-ISAM driver or the Microsoft Full-ISAM driver. In the Bridge profile, a record number segment of a key must reference the IDENTITY column of the Full-ISAM table and use the NTOC(), STR(), NTVNTOC(), or NTVSTR() functions to convert the IDENTITY column value to a character format. To use this feature, the option "RealRecordNumbers" must be enabled. o The Full-ISAM Bridge driver has been enhanced with two new conversion functions: STR() and NTVSTR(). These functions are similar to NTOC() and NTVNTOC(), but they use a simpler mask consisting only of spaces and a single "#" character. The "#" character is replaced with a default conversion of the number and any spaces are copied. The purpose of the STR() and NTVSTR() functions is to duplicate fields that are created by simple assignment or concatenation of numeric values: TheKey$ = "Name", RecNo Bridge profile example: KeyPart=IDCOL,5,7,"","0123456789",STR("#") o A new option has been added to the Full-ISAM Bridge driver profile to support programs that accidentally span a record boundary when reading string values. When set to TRUE, the option "TruncateSpanning" disables the normal "Illegal item number" (error 53) error that is reported when a program reads a character variable whose length extends beyond the end of the record. The driver will treat such reads as if the read ended exactly at the end of the record. Example: [FullISAMBridge] File=filename OpenAs=FoxPro Full-ISAM TruncateSpanning=True o The FoxPro Full-ISAM driver has been extended to support a SEARCH-equal operation on index 0 using a record number as the key value. Such searches can be performed on any FoxPro Full-ISAM file. Example: SEARCH = #5,0;R o The MySQL Full-ISAM driver has been extended to support a SEARCH-equal operation on index 0 using a record number as the key value. Such searches can be performed only on tables that contain an AUTO_INCREMENT column and a unique index based only on that column. The value of the AUTO_INCREMENT column is treated as the record number of the row. Example: SEARCH = #5,0;R o The MySQL Full-ISAM driver has been enhanced to support tables whose only unique index contains an AUTO_INCREMENT column. o The MySQL Full-ISAM driver has been enhanced to support the creation of tables with numeric IDENTITY (AUTO_INCREMENT) columns. A table can contain only one IDENTITY column which must be an integer type (such as 1%, 7%, %1, or %2). Creating a table with an IDENTITY column will automatically create a unique index based on that column (the primary key). Example: Def Struct REC Member S$ : Item "LABEL" Member %2,Id : Item "IDCOL" : Identity End Def Dim Rec. As REC Build #2,"test.table" As "MySQL Full-ISAM" Define Record #2;Rec. Close #2 o Four new GUI mnemonics, 'WCMSGASK', 'WCMSGERROR', 'WCMSGINFO', and 'WCMSGWARN', have been implemented to display standard Windows message dialog boxes. All of the mnemonics have three formats as shown below for the 'WCMSGASK' mnemonic: PChr$("Message");'WCMSGASK'; PChr$("Message","Title");'WCMSGASK'; PChr$("Message","Title","Options");'WCMSGASK'; The "Options" string determines the number and labeling of the buttons within the message box: "ARI" "Abort", "Retry", "Ignore" "O" "Ok" "OC" "Ok", "Cancel" "RC" "Retry", "Cancel" "YN" "Yes", "No" "YNC" "Yes", "No", "Cancel" The characters in the "Options" string may be in lower or upper case, but the first uppercase letter will select the associated button as the default button. The message box returns as input the uppercase label string of the button selected by the user followed by a carriage return. Example: Print PChr$("Continue?", "I/O Error", "yN");'WCMSGERROR'; Print 'IOEE K0'; Input "";I$ Select Case I$ Case "YES" . . Case "NO" . . End Select As with all other GUI mnemonics, this mnemonic can only be used with dL4Term or in dL4 for Windows. o A new GUI mnemonic, 'FRAME', has been defined for use with dL4Term or dL4 for Windows. The new mnemonic draws a frame around a specified rectangle. The mnemonic has two formats: PChr$(Left,Top,Right,Bottom);'FRAME'; PChr$(Left,Top,Right,Bottom,Type$);'FRAME'; The optional "Type$" parameter specifies the frame style which can be either "Sunken" ("S"), "Raised" ("R"), "Etched" (E), or "Bump" ("B"). If the "Type$" parameter is omitted or is "", the frame style will be similar to that of a 'WCSTRING' input box. When using the 'FRAME' mnemonic, sufficient space must be left around the rectangle to draw the frame. The frame is not a GUI element; it is drawn graphically like the 'RECT' mnemonic and the frame can be overwritten by characters or graphics. The frame color is determined by the current Windows color scheme and is not controlled by any of the color mnemonics. o A new function, MSC$(9), has been implemented to return the native absolute path of the directory containing the current program file. o A new utility, TESTLOCK, has been added to the Tools/ directory. This utility can be used to test network file system support for record locking. Use the command "testlock -h" to display usage instructions. o The dL4 QUERY utility (tools/query) has been extended to display whether a Full-ISAM field is an IDENTITY field. o The tools/term utility has been enhanced to optionally display the channels open on each monitored port. The "F" option ("term all mf") shows each open channel number, the filename open on the channel, and, if supported, the current record number. The record number is followed by a letter showing the lock status of the record. The status letters are "U" (unlocked), "L" (locked), and "B" (blocked waiting for a record lock). o The tools/term utility has been enhanced with a "B" option to display only ports that are blocked waiting for a record lock. For each blocked port, the utility finds and displays the port number of the program which is currently locking the desired record. Example: term all mb o New options have been added to the tools/query utility. The "-p" option enables division of long displays into screen sized pages. The "-l", "-l=$printer", "-l=path" options direct output to the "$lpt" printer, "$printer" printer, or the "path" text file respectively. o The PORT mode 7 statement has been enhanced to optionally return the group name, current directory path, terminal type, numeric account, and numeric group for the selected port. The group name, numeric account, and numeric group values are returned as "" under Windows. PORT portnum,7,status,userid$,station$,group$,dir$,term$,usern$,grpn$ Note that the PORT mode 7 statement may have between 5 and 10 parameters. o The PORT statement has been extended with a new mode, 8, that returns the open channels on the specified port. The statement PORT portnum,8,status,firstchan,lastchan,chaninfo.[] returns open channel information into the array 'chaninfo.[]' for channels between 'firstchan' and 'lastchan'. The 'chaninfo.[]' variable must be an array of structures using the following structure definition: Def Struct CHANINFO Member 1%,ChanNum Member Path$[200] Member 3%,RecordNum Member 1%,RecordState End Def The member names, dimensioned size of the Path$ member, and the numeric precisions of the other structure members can be varied as desired. The filename returned in Path$ may be truncated if it is longer than Path$ or if it exceeds system limitations. If the number of open channels in the specified range is less than the dimensioned size of 'chaninfo.[]', then the first unused element of the array will have a ChanNum value of -1. If the number of open channels in the specified range is greater than the dimensioned size of 'chaninfo.[]', the extra channels will be ignored. o The PORT statement has been extended with a new mode, 9, that determines if a specified file is open on the port and optionally determines if a specified record number is locked in the file. The statement PORT portnum,9,status,filepath$,recordnum,channum performs an inquiry on port 'portnum' to determine if it has 'filepath$' open on a channel with the record 'recordnum' locked. If 'recordnum' is negative, the search will be performed using only the file path. If a match is found, the channel open to the file will be returned in 'channum'. If a match is not found, then 'channum' will be set to -1. o The CALL MONITOR() procedure in the tools/oldcalls.lib compatibility library has been enhanced to return current directory, terminal type, and open channel information. o The EOPEN statement and the intrinsic CALL LOCK() can now be used with text files. If a text file is opened using EOPEN or locked with CALL LOCK(), the file cannot be opened by other dL4 users. Unlike portable contiguous and formatted files, the EOPEN statement will succeed on text files that have been opened for shared usage by other ports. o The EOPEN statement and the intrinsic CALL LOCK() can now be used with uniBasic (non-Universal) Indexed Contiguous, Contiguous, and Formatted files. If a file is opened using EOPEN or locked with CALL LOCK(), the file cannot be opened by other dL4 users. Unlike portable or Universal contiguous and formatted files, the EOPEN statement will succeed on uniBasic files that have been opened for shared usage by other ports (this is compatible with uniBasic behavior). o A new driver, "Device Text", has been added to dL4 to support opening devices and named pipes as line oriented bidirectional text streams. Example: Open #3,"pipename" As "Device Text" Print #3;"xxxxxx" Read #3;S$ o The intrinsic CALL SORTINSTRING() has been extended to support sorting arrays of strings or arrays of structures where the first structure member is a string. New formats: Call SortInString(status,keycnt,keylen,keys$[],work$) Call SortInString(status,keycnt,keylen,keys.[],work.) The 'work$' and 'work.' variables should be identical to individual elements of the 'keys$[]' and 'keys.[]' arrays. The 'keylen' value specifies the maximum number of significant characters in the sorted values and can be used to perform a sort on the first 'keylen' characters of each key value. o Two new intrinsic string functions have been added to simplify replacing string values within a string. The function Replace$(Source$,Old$,New$,Count) returns the string 'Source$' replacing the first 'Count' occurrences of the string 'Old$' with the string 'New$'. All occurrences of the string may be replaced by omitting the 'Count' parameter or using 'Len(Source$)' as the value of 'Count'. The function ReplaceCI$() is identical to Replace$() except that it uses a case-insensitive search for 'Old$'. Since Replace$() and ReplaceCI() are intrinsic functions, a DECLARE statement is required in order to use the new functions. o The statement SYSTEM 33,"C:\\Program Files\\Application\\program.exe",S will try to execute "program.exe" on the user's PC. The variable "S" will be set to zero if the program was successfully started and non-zero if the program couldn't be started. Unlike SYSTEM or SYSTEM 31, the statement does not wait for the program to finish and exit. This statement is intended for use with dL4Term or dL4 for Windows. o The intrinsic CALL PROGRAMDUMP, the PDUMP command, and the force port dump feature now support options to control line width and to enable printing string values that include nulls. The options are: COLUMNS= NULLS= Options are specified in the CALL PROGRAMDUMP options parameter or in an options ("(options. . .)") field in the filename. The default line width is now 78 columns and long lines will be broken into multiple lines to improve readability. A width of zero will print lines of any width in a single line. The NULLS options may be used with or without a boolean value (the option "NULLS" is equivalent to "NULLS=TRUE"). If enabled, null characters in a string are printed as "\0\". o A new utility, BITSTERM, is available in the Tools/ directory. The BITSTERM utility is identical to the uniBasic TERM utility. o Behavior change: the object revision in program files is now set more accurately. This improvement will permit more programs saved under a current version of dL4 to run under older versions of dL4. o Behavior change: tab characters in source line comments are expanded into spaces using the indentation value as the tab width. o Behavior change: TRACE output now includes program file name and procedure name if they are available. o Bug fixed: message queues belonging to other ports were sometimes deleted when a new dL4 session was started on a busy system. o Bug fixed: RUN and LOADSAVE would sometimes hang after running on some Linux systems (usually multiprocessor systems). o Bug fixed: the dL4 IC2FI (tools/ic2fi) utility did not allow users to convert files if the original key length of an index was longer than the key length in the bridge profile. This prevented conversion of files because key lengths in Indexed Contiguous files are normally rounded up to even values and are thus longer than the actual key size. The utility now displays a warning message, but allows the user to continue conversion. o Bug fixed: when using dL4Term, the EDIT command deleted all "\177\" characters from string literals. o Bug fixed: the PORT 6 statement returned zero instead of -1 when the blocking port number was unknown. o Bug fixed: in various drivers, open options were ignored if they occurred after a boolean open option. Feb 9 2004 (Maintenance Release 5.2.6) o Bug fixed: input timeout on terminals, devices, and files sometimes failed on Linux systems causing applications to hang or lose data due to buffer overflow. o Bug fixed: the dL4 IC2FI (tools/ic2fi) utility did not allow users to convert files if the original key length of an index was longer than the key length in the bridge profile. This prevented conversion of files because key lengths in Indexed Contiguous files are normally rounded up to even values and are thus longer than the actual key size. The utility now displays a warning message, but allows the user to continue conversion. o Bug fixed: when using dL4Term, the EDIT command deleted all "\177\" characters from string literals. Jan 9 2004 (Maintenance Release 5.2.5) o Bug fixed: packed data was sometimes written incorrectly to uniBasic or Universal indexed-contiguous, contiguous, and formatted files. o Bug fixed: the "L" command in the KEYMAINT and DOKEY utilities did not display the record number or key length. Aug 12 2003 (Maintenance Release 5.2.4) o Behavior change: support READ RECORD and WRITE RECORD of arrays with uniBasic indexed contiguous files. This matches the behavior of portable indexed contiguous files. o Bug fixed: the DUPLICATE statement produced incorrect filenames for FoxPro Full-ISAM files if a trailing "!" was used. o Bug fixed: the bridge driver could not insert records in a MySQL table if a key contained a DECIMAL(n,0) column. Jul 3 2003 (Maintenance Release 5.2.3) o Compatibility with RedHat 9 Linux has been improved. o Behavior change: the printer/pcl.prf and printer/simple.prf printer definition files have been modified to ignore illegal characters rather than generating an illegal character error. o Bug fix: the MAKEHUGE utility did not work with indexed contiguous files that had key translation filters defined. May 16 2003 (Maintenance Release 5.2.2) o A new option, "uselust", has been added to the DL4LUST environment variable to import a search path from the "LUST" environment variable. The imported search path is placed after any entries in DL4LUST. Example: DL4LUST="(uselust)" export DL4LUST o A new intrinsic function, CALLSTAT$(), has been implemented to return a string describing the program position at a specified level in the procedure stack. This function would typically be used to generate information for an error log. The procedure stack includes all function, procedure, Call-Subprogram, and SWAP levels. The level type ("Swap", "SubPgm", "ExtSub", "ExtFunc", "IntSub", "IntFunc", or "") is returned in a function argument. The current position is level 0, the caller is level 1, and so on. An error 38 is generated if a non-existent level is specified. BASIC syntax: CallStat$(Level, LevelType$) Example: Print "Caller position is ";CallStat$(1,Type$) Print "Caller type is ";Type$ o The SCOPE BASIC mode LIST command now supports a "-c" option to disable paging of the listing. o The tools/convert.prf and tools/convbits.prf conversion profiles have been enhanced with examples for the "[CallByFilename]" section, the "[OutputFormat]" section, and the ReportUndefinedProcedures setting. o Behavior change: ports belonging to another user can now be evicted without root privileges if the target port has the environment variable DL4ACCEPTPORTCMDS set to TRUE. o Bug fix: when an indexed contiguous file was opened in read-only mode (ROPEN), recent changes to the index were sometimes ignored. o Bug fix: the FoxPro Full-ISAM driver "dataext" option created files with duplicated extensions ("file.ext.ext"). Apr 25 2003 (Maintenance Release 5.2.1) o The window driver can now use "clear to end of line" operations to improve performance on "magic cookie" terminals such as the Televideo 925. To enable this feature, the line "UseCL=True" must be added to the "[Settings]" section of the terminal definition file (for example, the "tvi925" file). This optimization may cause problems on some terminals or terminal emulators that have non-standard "clear to end of line" operations and, for this reason, the feature is not enabled by default. o The "TCP Listen Socket" driver has been enhanced to accept a new OPEN option. The new "REUSE" option enables the driver to open a socket with a port number that is already in use. This option is needed to support certain network protocols and to avoid error 76 ("File or device is open elsewhere") when re-opening a previously used TCP port number. Example: Open #1,"(reuse):9631" As "TCP Listen Socket" o The "MySQL SQL" and "MySQL Full-ISAM" drivers have been enhanced to accept a "PORT=" option in the OPEN statement or in the DL4MYSQL/DL4MYSQLISAM runtime parameters. This option makes it possible to use MySQL servers with non-default port numbers. o A new intrinsic CALL, IMSPACK(), has been implemented to provide compatibility with CALL $PACK in IMS BASIC. The syntax of CALL IMSPACK() is: Call IMSPack(Mode, Src$, Dest$) Call IMSPack(Mode, Dest$, Src$) where "Mode" equals zero packs characters from "Src$" into "Dest$" and a non-zero "Mode" unpacks characters from "Src$" into "Dest$". The packing algorithm uses a radix 50 style mechanism. o A new intrinsic CALL, TRANSLATE(), has been added to translate strings to or from binary strings according to a specified character set. The syntax and arguments of CALL TRANSLATE() are: Call Translate(DestCnt,Dest$,SrcCnt,Src?,CharSet$) Call Translate(DestCnt,Dest?,SrcCnt,Src$,CharSet$) DestCnt - receives the number of characters translated into the destination. Dest$ - destination string that receives the characters translated from Src?. Dest? - destination binary string that receives the characters translated from Src$. SrcCnt - receives the number of characters translated from the source. Src$ - source string of characters to be translated. String terminator characters are copied as data and the source size is controlled by the total size of the variable and any double subscripting. Src? - source binary string of bytes to be translated. The source size is controlled by the total size of the variable and any double subscripting. CharSet$ - character set name such as "ASCII", "ANSI", or "UTF-8". If a character cannot be translated, translation will stop. Translation errors can be detected by comparing the returned source translation count to the source size. o A new option, "P", has been added to the "TERM" utility to page long listings of active ports. The command "term all mp" would list all active ports in screen sized pages. o A new option "ADD" has been implemented in the "PGMCACHE" utility to manual add permanent entries to the program cache. The command "pgmcache add filename" would add the program or library "filename" to the program cache. The file would remain in the cache until the cache itself was deleted or the system was restarted. o Bug fix: the CHARSET and NUMMAP options could not be used when building a formatted file. Apr 2 2003 (Release 5.2) o Platform 6D, Linux x86, is now compiled and linked on RedHat 7.3 Linux. This platform update from RedHat 6.1 adds support for files larger than 2 gigabytes, but may cause incompatibilities with old Linux systems (RedHat 6.x or earlier). It is recommended that Linux systems should be upgraded to RedHat 7.1 or later or other similar Linux versions. o A new driver, "MySQL SQL", has been implemented so that applications can use SQL statements to issue commands and queries to a MySQL server. The driver allows an application to access the full capabilities of MySQL including both standard SQL syntax and MySQL specific features. Due to MySQL licensing requirements, the driver cannot be used without a special SSN product option. Please contact the Dynamic Concepts Sales department for information on obtaining the required SSN. The OPEN statement uses a special filename syntax with two formats: "server:database" and "database". Rather than opening a specific table, the OPEN statement creates a connection to a MySQL server and sets the default database to be used by SQL statements. If the server name is not specified, the system on which the program is running will be used as the server (unless a default server is specified in the DL4MYSQL runtime parameter, see below). The OPEN statement also supports four comma separated options: "user=name", "password=string", "pswd=string", and "rtrim=boolean". These options supply server login identification and, in the case of "rtrim", control whether character fields are returned space filled (default) or with trailing spaces removed ("rtrim=true"). Examples: OPEN #1,"mysystem:accounting" AS "MySQL SQL" OPEN #5,"(user=bill,pswd=secret)testdb" AS "MySQL SQL" The server name and login information can be specified in the environment variable "DL4MYSQL" which supports the comma separated options "server=name", "user=name", "password="name", and "pswd=name". Example for a Unix command line shell: $DL4MYSQL="server=myserver,user=anonymous" $export DL4MYSQL $scope SQL statements are executed by using SEARCH statements. Each SEARCH statement specifies a channel open to a MySQL server and an SQL statement as a character string. Examples: SEARCH #1;"select * from testtable" SEARCH #5;"update acctgtbl set balance=123.45 where account=19765" SEARCH #5;"drop table testtable" If the statement fails, an error will occur. Syntax errors in SQL statements are reported as error 274, "SQL syntax error". After an SQL SELECT statement is successfully executed, the number of rows in the result set can be determined by using the CHF(channel) function. The result set itself is read by using normal READ and READ RECORD statements. An error 52, "record not found", will be reported by any statement attempting to read beyond the end of the result set. Example: Search #7;"select account, balance from acctgtbl" Print Chf(7);"rows returned by query" Do Try Read #7;Account,Balance Else Exit Do Print "Account =";Account;" ";Balance =";Balance Loop Note: the result set of the current SQL SELECT statement is copied into memory by the dL4 SEARCH statement. SELECT statements should be written so as to limit the size of the result set to a reasonable value. An SQL LIMIT clause can be used in the SQL SELECT statement to restrict the maximum size of the set. The MAP RECORD statement can be used to map structure variable members according to their item names to the columns returned by a query. In the following example, the SQL select statement returns a two column result "account, balance" which is mapped into a structure variable that uses the opposite ordering: Def Struct RSET Member 3%,Balance : Item "balance" Member 3%,Acct : Item "account" End Def Dim R. As RSET Search #7;"Select account, balance from acctgtbl" Print Chf(7);"rows returned by query" Map Record #7 As RSET Do Try Read Record #7;R. Else Exit Do Print "Account =";R.Acct;" ";Balance =";R.Balance Loop NULL values in numeric, date, or character columns are converted to special values when they are read. When adding new rows or modifying existing rows, NULL values can be written by using the same special values. In this version of dL4, the special values are -1E62 for numeric values, "January 1, 0001" for date values, and "\xffff\" for strings. Programs should not test for or set these values directly. Instead, new intrinsic functions have been provided to test for NULL values and to set NULL values. The intrinsic function IsSQLNull() returns 1 when its argument is a NULL value and 0 for all other values. The intrinsic functions SQLNull(), SQLNull#(), and SQLNull$() return the special NULL values for numbers, dates, and strings. NULL values cannot be read into or written from integer numeric variables or 1% date variables. NULL values are not supported for binary variables ("B?"). Three new intrinsic functions, SQLV$(), SQLN$(), and SQLNV$() are provided to make it easier to construct SQL statements. The SQLV$() function takes one or more arguments of any non-array type and returns a string containing the argument values encoded for use by an SQL driver. The SQL driver detects such encoded values in the SEARCH statement string and formats the values as required by the SQL server. This formatting guarantees proper quoting of character string values and places commas between each value. If the argument is a structure variable, each member of structure is encoded. The SQLN$() function takes a single structure variable argument and returns a string containing the member item names encoded for the SQL driver with commas separating each name. The SQLNV$() function takes a single structure variable argument and returns a string containing the member names and values encoded for the SQL driver with equals signs ("=") and commas. Examples: Search #1;"Insert test (count,label) Values ("+SQLV$(C,L$)+")" Search #1;"Insert test ("+SQLN$(R.)+") Values ("+SQLV$(R.)+")" Search #1;"Update test Set "+SQLNV$(R.)+" where count=19" o A new driver, "MySQL Full-ISAM", has been implemented to support Full-ISAM and Bridge access to MySQL database tables. Due to MySQL licensing requirements, this driver cannot be used without a special SSN product option. Please contact the Dynamic Concepts Sales department for information on obtaining the required SSN. The MySQL driver implements the standard Full-ISAM driver interface with the following modifications: 1. The InnoDB table type must be used in order to support record locking. Other table types may be usable, but they will not support record locking. 2. A table must have at least one unique index in order to support reading or writing. A table without a unique index can be opened only to extract table information or to add indexes. 3. The OPEN statement uses a special filename syntax with the two formats: "server:database.table:" and "database.table". If the server name is not specified, the system on which the program is running will be used as the server. The OPEN statement also supports four comma separated options: "user=name", "password=string", "pswd=string", and "rtrim=boolean". These options supply server login identification and, in the case of "rtrim", control whether character fields are returned space filled (default) or with trailing spaces removed ("rtrim=true"). Examples: OPEN #1,"mysystem:accounting.customers" AS "MySQL Full-ISAM" OPEN #5,"(user=bill,pswd=secret)test.info" AS "MySQL Full-ISAM" 4. The KILL statement uses the same filename syntax as the OPEN statement and supports the "user=name", "password=string", and "pswd=string" options. Example: KILL "(user=bill,pswd=secret)test.info" AS "MySQL Full-ISAM" The server name and login information can be specified in the environment variable "DL4MYSQLISAM" which supports the comma separated options "server=name", "user=name", "password="name", and "pswd=name". Example for a Unix command line shell: $DL4MYSQLISAM="server=myserver,user=anonymous" $export DL4MYSQLISAM $scope The MySQL driver has been tested with MySQL versions 3.23.42 through 3.23.53. InnoDB tables are an optional feature of MySQL and require installing both an InnoDB capable version of MySQL and setting optional configuration parameters. Please see the MySQL documentation for information on installing and configuring a MySQL server. o The new MySQL Full-ISAM driver has an open option, "nulls=true", to support read and writing NULL values to table columns. When a table is opened with the "nulls=true" option, NULL values in numeric, date, or character columns are converted to special values when they are read. When adding new records or modifying existing records, NULL values can be written by writing the same special values. Currently, the special values are -1E62 for numeric values, "January 1, 0001" for date values, and "\xffff\" for strings. Programs should not test for or set these values directly. Instead, new intrinsic functions have been provided to test for NULL values and to set NULL values. The intrinsic function IsSQLNull() returns 1 when its argument is a NULL value and 0 for all other values. The intrinsic functions SQLNull(), SQLNull#(), and SQLNull$() return special NULL values for numbers, dates, and strings. NULL values cannot be read into or written from integer numeric variables or 1% date variables. NULL values are not supported for binary variables ("B?"). NULL values can be used in keys and index columns, but it is not recommended. Example: Declare Intrinsic Function IsSQLNull,SQLNull,SQLNull#,SQLNull$ Open #1,"(nulls=true)server:database.table" As "MySQL Full-ISAM" ! Display table with possible NULL values Do Try Read Record #1;R. Else Exit Do Print "Name = ";R.CustomerName$ Print "Appointment = "; If IsSQLNull(R.AppointmentDate#) Print "none" Else Print R.AppointmentDate# End If Loop ! Add new record with NULL value R.CustomerName$ = "John Quinn" R.AppointmentDate# = SQLNull#() Add Record #1;R. o The MySQL Full-ISAM driver supports the special MySQL date value of 0000-00-00. Such date values can now be read into date variables and will set the date variable to be "Not-A-Date". The special value of 0000-00-00 can be written by writing a date value of "Not-A-Date". A date variable can be set to "Not-A-Date" by the CLEAR statement ("CLEAR D#"). An error 15 will occur if a "Not-A-Date" value is used in a date function or date expression. o The MySQL Full-ISAM driver reports character fields in indexes as case insensitive when a GET statement retrieves index information (if the MySQL server is using the standard case insensitive character set). When creating a table, the driver will accept index field definitions that are either case sensitive or case insensitive. The actual case sensitivity is always controlled by the MySQL server. o The KILL statement now supports an options field "(...)" before each filename to supply driver options. Example: KILL "(user=fred,password=secret)mytable" AS "MySQL Full-ISAM" The SCOPE/BASIC KILL command does not support deleting MySQL tables. o The Full-ISAM Bridge driver has been extended to support Full-ISAM date fields and translation of field types. A date field is used by specifying a translation function in the field definition that defines how to translate a date value to or from a character or numeric field. Translation functions also support converting Full-ISAM numeric fields to Indexed-Contiguous character key fields. Additional functions support subscripted character fields for key fields or case-insensitive key fields. The translation functions are: DTOC(mask) Convert the Full-ISAM date field to a character string in the record image using "mask". All dates use local date/time. When the DTOC() function is used in an index definition, the "mask" must define a sortable date. For example, "YYMMDD" is a legal index mask, but "MMDDYY" is not because it would not sort correctly. "mask" is a quoted string in which the following substrings have special meaning: YYYY Four digit year YY Two digit year with the century set so it is within 50 years of the current date. AA Two digit year in which years after 1999 are specified as "A0" through "E9". MM Zero filled month, 1 - 12 DD Zero filled day of month, 1 - 31 DDD Zero filled day of year, 1 - 366 DDDDD Zero filled day relative to base year 1968. January 1, 1968 is "00001". Six or more "D"s can be also be used. HH Zero filled hour of day MM Zero filled minute of hour SS Zero filled second of minute DTON(mask) Convert Full-ISAM date field to a decimal number in the record image using "mask". All dates use local date/time. "mask" is a quoted string defining the decimal digits of the number. The following substrings in the mask have special meanings: YYYY Four digit year YY Two digit year with the century set so it is within 50 years of the current date. MM Month, 1 - 12 DD Day of month, 1 - 31 DDD Day of year, 1 - 366 or 0 - 365 DDDDD Day relative to base year 1968. January 1, 1968 is 1. Six or more "D"s can be also be used. HH Hour of day MM Minute of hour SS Second of minute NTOC(mask) Convert Full-ISAM numeric field to a character string according to the USING mask "mask". The mask must use a period (".") for any decimal point point and comma as any grouping separator. NTVNTOC(mask) Convert Full-ISAM numeric field to a character string according to the USING mask "mask" and using locale information to determine the decimal point character. The mask must use a period (".") for any decimal point and comma as any grouping separator. LEFT(len) Use the first "len" characters of the field. This function can only be used in index definitions and the field must also be used in the "[Record]" section. UCASE(len) Use the first "len" characters of the field converted to uppercase. This function can only be used in index definitions and the field must also be used in the "[Record]" section. LCASE(len) Use the first "len" characters of the field converted to lowercase. This function can only be used in index definitions and the field must also be used in the "[Record]" section. Examples: Field=LASTPAYMNT,114,2%,,,DTON("YYDDD") KeyPart=DATE1,0,10,"","0123456789",DTOC("YYYYMMDD") KeyPart=NUM2,5,7,"","0123456789",NTOC("####.##") o The Full-ISAM Bridge driver profile has been extended to support two conversion functions, IFNULL and IFERR, that convert SQL NULL or invalid values to and from the values needed in the emulated indexed contiguous file record. The IFNULL function takes a single string argument which defines a string or number that is stored into the converted field whenever a NULL is read. When a record is written, the same value will be converted to a NULL. Examples: Field=COUNT,28,4%,,,IFNULL("-1") Field=ACCTID,16,12,,,NTOC("-------#.##"),IFNULL("N/A"),Strip In order to read or write NULLs, the SQL driver options in the bridge profile must be set to enable reading and writing nulls (for the MySQL Full-ISAM driver, see the "nulls=true" option described above). The IFERR function is similar to the IFNULL function, but it is applied to invalid numeric or date values. In this release of dL4, the only possible invalid value is the special MySQL date value of "0000-00-00". If no IFERR function is specified, an invalid value results in an error. In the following example, MySQL "0000-00-00" dates are converted to -1 while actual dates are converted to decimal numbers in the form "YYYYMMDD": Field=DATE1N,60,3%,,,DTON("YYYYMMDD"),IFERR("-1") In this example, "0000-00-00" dates in a key part are converted to the string "00000000" while actual dates are converted to strings in the format "YYYYMMDD": KeyPart=DATE1,0,8,"","0123",DTOC("YYYYMMDD"),IFERR("00000000") Both IFNULL and IFERR functions can be used in the same field or key part definition. o The Full-ISAM Bridge driver profile has been extended to support filler fields. A filler field is any record field with a field name beginning with an asterisk. Filler fields are not read from the Full-ISAM file, but they are initialized to the fill character or zeroed if the fill character is not defined. The filler name is treated as a comment. Example: Field=*fillerwithnulls*,54,5 Field=*fillerwithblanks*,59,5,," " o The numeric precision syntax in Full-ISAM Bridge profile files has been extended to specify the number of decimal places needed. The new, optional format is "p.d%" where "p" is the dL4 numeric precision (1-4) and "d" is the number of decimal places. Thus "3.2%" would specify a 10 digit floating point format with two decimal places. The decimal place information is used by the tools/ic2fi utility to create Full-ISAM files when the Full-ISAM driver supports only fixed point, rather than floating point, numbers. Example: Field=COST,80,3.2% o A new option has been added to the Full-ISAM Bridge driver profile to disable use of temporary record values when inserting or modifying records. The temporary values are normally used to reserve key values after SEARCH mode 4 insert statements and thus prevent other programs from inserting the same key. If the new "ProtectKeys=False" option is specified in the initial section of a bridge profile, SEARCH mode 4 statements will check for the current existence of a key value, but the Full-ISAM file will not be modified until all keys have been inserted for the record. This option improves Bridge driver performance and allows use of foreign key constraints in SQL tables. If the option is used, duplicate key errors may occur after a successful SEARCH mode 4 insertion of the key. Bridge profile example: [FullISAMBridge] File=filename OpenAs=FoxPro Full-ISAM ProtectKeys=False o The Full-ISAM Bridge driver support of SEARCH mode 6 (search less than) has been improved. Statements such as SEARCH #Chan,6,IdxNum;"{",R,S can now be used on indexes that use date or numeric conversion functions. The driver will detect that the key value is greater than any possible key value and will search for the last key in the specified index. In the previous release, the key value "{" would have caused an error in the conversion function because "{" is an illegal value. o The tools/ictofi utility program has been replaced with a new utility, tools/ic2fi, that offers similar, but greatly improved, features to convert from Indexed-Contiguous files to Full-ISAM files. The new utility can also be CALLed as a subprogram to perform automated or repetitive conversion of Indexed-Contiguous files. The ic2fi utility is documented in the dL4 5.2 Product Training manual which can be downloaded from www.dynamic.com or ftp.dynamic.com. o The tools/buildfi utility program has been enhanced to allow selection of the Full-ISAM type (FoxPro or SQL) and to improve error handling. o A new GUI mnemonic, 'WCMARKCOLOR', has been defined to set the text and background colors for items that have been selected by the user in GUI list boxes ('WCLIST', 'WCEDITLIST', ...). The colors are also used for items selected by the 'WCMARK mnemonic. If the 'WCMARKCOLOR' mnemonic is printed to a window, all GUI list elements subsequently created in that window will use the specified colors. The 'WCMARKCOLOR' mnemonic can be printed to a GUI element box to set or change selection colors in only that GUI element. The 'WCMARKCOLOR' mnemonic has three formats: 'WCMARKCOLOR' - use the current window text and background colors 'fg WCMARKCOLOR' - use "fg" as the text color and the current window background color 'fg,bg WCMARKCOLOR' - use "fg" as the text color and "bg" as the background color. The color values "fg" and "bg" are numbers between -6 and 2^24 as used in the 'FONTCOLOR' and 'BACKCOLOR' mnemonics. The 'WCRESETCOLOR' mnemonic can be used to restore the standard selection colors. As with all other GUI mnemonics, this mnemonic can only be used with dL4Term or in dL4 for Windows. o Two new GUI mnemonics, 'WCSETCOLOR' and 'WCRESETCOLOR', have been defined to set the text and background colors in newly created GUI elements. The 'WCSETCOLOR' mnemonic copies the current window foreground and background colors. The 'fg bg WCSETCOLOR' mnemonic sets the GUI element text and background colors according to the RGB color values "fg" and "bg". The standard system colors can be restored by the 'WCRESETCOLOR' mnemonic. These mnemonics can be printed to a GUI element after it is created to change its current colors. As with all other GUI mnemonics, these mnemonics can only be used with dL4Term or in dL4 for Windows. o A new GUI mnemonic, 'n WCASKCOLOR', has been implemented to display the standard window color selection dialog and return the color selected, if any, by the user. The mnemonic requires a single numeric parameter which is the default RGB color for the dialog. The dialog returns the selected color as a decimal input string followed by a carriage return. If no color is selected, a null string will be returned followed by a carriage return. As with all other GUI mnemonics, this mnemonic can only be used with dL4Term or in dL4 for Windows. o The PORT statement has been extended with a new mode, 6, to determine whether a port is blocked by a record lock and which other port is holding the needed record lock. The statement PORT portnum,6,status,isblocked,blockingport sets the variable "isblocked" to one if the dL4 program running on port "portnum" has been waiting for over 20 seconds for a record lock and to zero if it is not blocked. If the port is blocked by a record lock, the variable "blockingport" is set to the port number of the program that currently has the record locked or to -1 if the blocking port number cannot be determined. PORT mode 6 is supported for record locks on formatted, contiguous, and indexed contiguous files. o The PORT statement has been extended with a new mode, 7, to return the user name and work station name of a specified port. The statement PORT portnum,7,status,userid$,station$ queries port "portnum" and returns in "userid$" the user name, if any, associated with the port and returns in "station$" the terminal name, if any, used by the port. o The TERM utility has been extended to display the user name and work station (terminal) name associated with each port. If the program running on a port is currently blocked by a record lock wait, its state will be displayed as "Blkd" and the port number that is currently holding the locked record will be displayed in parentheses. The "Blkd" state information is supported only for record locks on formatted, contiguous, and indexed contiguous files. o The intrinsic CALLs GetGlobals() and SetGlobals() have been extended to support separate named sets of global values. If the first parameter of CALL GetGlobals() or CALL SetGlobals() is a string, it will be treated as a global set name and the get or set operations will be applied using that global set. The default set is named "". A global set is created by the first CALL SetGlobals() using the set name. Examples: Call SetGlobals$("mylib",0,N$,A) ! set values in "mylib" Call GetGlobals$("mylib",0,N$,A) ! get values from "mylib" Call SetGlobals("mylib") ! delete the set "mylib" o The intrinsic CALL table in the dL4 development kit, userproc.c, now supports the option USERPROCOPT_CVTSTRINGS to automatically string parameters to and from binary ITEMS using the UniBasic IRIS character set. This option can be used to simplify conversion of CALLs from UniBasic at the cost of some additional overhead. See the files usercall/userproc.h and usercall/userproc.c in the development kit for details. o A new driver, "Socket Text", has been added to provide text line oriented I/O to TCP sockets. Driver arguments and usage is identical to the raw socket driver except that READ and INPUT statements will read data in lines terminated by carriage return and/or line feed. o A new open option, "SYNC", has been added to the Portable Contiguous, Portable Indexed-Contiguous, and text file drivers. This option forces the operating system to write data immediately to disk. Example: Open #1,"(sync)datafile" This option will severely impact file throughput and should only be used in special circumstances. o A new option, "buffer=true", has been added to the text and pipe drivers to improve performance. For compatibility with UniBasic, these drivers normally output data immediately after a PRINT or WRITE statement. The "buffer=true" option instructs the drivers to delay output until an internal buffer is filled or the driver is closed. The option can be used in an OPEN statement or in a printer script "# dl4opts=" line. Examples: BUILD #1,+"(buffer=true)textfile!" # dl4opts=buffer=true o Portable Indexed-Contiguous and Portable Contiguous file performance has been improved for files opened in exclusive mode. Scratch files should be opened using the EOPEN statement to obtain this increased performance. o It is now possible to output binary zero characters to a terminal or serial port when in binary output mode. The MAT WRITE statement will output all characters including binary zero characters in a string variable. Subscripts can be used to limit output to a selected range within a string. o A new BASIC command, XBREAK, has been implemented to allow the user to set breakpoints outside of the current program. The command uses the same syntax as the existing BREAK command, but will apply the breakpoint to both the current program and to any program entered via CHAIN, CALL subprogram, or SWAP statements. Example: XBREAK 1000 XBREAK breakpoints can be deleted or listed with the normal NOBREAK or STATUS BREAKPOINT commands. o Enhancement: the "wyse60" and "wyse60-43" terminal definition files now recognize either form of the INSERT key to toggle the input edit insert mode. o Enhancement: the "wyse60" and "wyse60-43" terminal definition files now support the 'PGMFN' mnemonic to program function keys. o Enhancement: quoted values can now be used in driver options. For example, a quoted value might be used to provide a subject line using parentheses to the email driver: Open #1,"(From=someone,Subject=''(test)'')somebody" As "Email" o Behavior change: the DL4PORTDUMP and DL4STOPDUMP runtime parameters have been enhanced to support an optional file protection ("") specification. o Behavior change: the LOADSAVE utility now prints a simple usage message if the "-h" option is used. A full usage message can be displayed by using the "-H" option. o Bug fixed: the SPAWN statement sometimes failed when a program path included embedded spaces. o Bug fixed: searching or reading backwards through an index in the MySQL Full-ISAM driver skipped records that had keys beginning with NULL values. o Bug fixed: the statement "ENTER ..." always generated an illegal word error. o Bug fixed: storing a value into a "%2" (32-bit integer) structure member caused alignment violations on some systems (such as Sun SPARC systems). o Bug fixed: the POS() function did not work correctly when a negative step value was used with the "IS" or "EXCEPT" relational operators. o Bug fixed: OPTION DIALECT IRIS1/BITS1/IMS did not allow values to be returned in subscripted strings parameters of intrinsic CALLs or functions. o Bug fixed: when converting source files, functions in CALL arguments were sometimes converted to variables. o Bug fixed: the 'EPW' mnemonic could not be defined in terminal definition files. o Beta bug fixed: memory violations occurred if auto-increment columns or null values were used in MySQL tables. o Beta bug fixed: MySQL indexes were not recognized as case-insensitive. o Beta bug fixed: SCOPE and RUN could not be used under SCO OpenServer 5.0.5 with the original system socket libraries. o Beta bug fixed: the MySQL driver was always reported as "not licensed" by RUN (it worked properly in SCOPE). Jan 3 2003 (Maintenance Release 5.1.5) o Platform E9 (HPUX) software is now compiled for HPUX version 11 rather than version 9. This and later releases of dL4 for HPUX may not be fully compatible with versions 9 or 10 of HPUX. o Bug fixed: a memory violation sometimes occurred after an error 15, "arithmetic overflow", was detected in the argument list of a user defined function or procedure. Dec 23 2002 (Maintenance Release 5.1.4) o Bug fixed: an error 5 ("Illegal character") occurred whenever the 'BCTRACK' ("Begin Cursor Tracking") mnemonic was used and a window was open or the window system was active. o Bug fixed: if a program executed a SWAP statement using CHAIN WRITE statements, then any subsequent CHAIN or SWAP statement in the parent program would not pass common ("COM 3%,N") variables. o Bug fixed: when converting programs using the CONVERT command or the LOADSAVE "-c" option, intrinsic functions in CALL parameters were sometimes converted to array variable references. o Bug fixed: a memory violation sometimes occurred in printer scripts that used the TRANSLATE= option if the output path was incorrect. o Bug fixed: the 'EPW' mnemonic could not be defined in terminal definition files. Nov 25 2002 (Maintenance Release 5.1.3) o A new environment variable, DXTESTCOPY, has been implemented for use in debugging DynamicXport applications. When the DXTESTOUT environment variable is defined, a "CALL DXCLOSE()" statement outputs the current DynamicXport output table to the text file selected by DXTESTOUT. The DXTESTCOPY value, if defined, selects which, if any, values from the DynamicXport input table should be copied to that text file. If a selected value exists in both the input and output tables, only the output table value will be written to the text file. DXTESTCOPY is a comma separated list of value names or value name prefixes as in the optional CALL DXCOPY() or CALL DXMOVE() selection arrays. Examples: To copy all input table variables with names beginning with "U_" DXTESTCOPY=U_ export DXTESTCOPY To copy all input table variables DXTESTCOPY=+ export DXTESTCOPY o Behavior change: the pipe driver ('OPEN #c,"$command"') now sets standard error in the pipe child process to output to /dev/null. Previously, error messages output by the child process were output to the parent's standard error. This corrupted the user's screen or caused other problems. o Bug fixed: opening the pipe driver with an AS clause sometimes resulted in a syntax error. o Bug fixed: a BUILD statement with an AS clause using "" or "AutoSelect", caused a memory violation. o Bug fixed: POS() expressions without relational operators were not treated as syntax errors. o Bug fixed: when using DynamicXport, HTML files with long lines (499 characters or more) did not work correctly. o Bug fixed: when using DynamicXport, "dl4l()" references did not work correctly if the list variable was empty. Sep 27 2002 (Maintenance Release 5.1.2) o A new mnemonic, 'DEFAULTCOLOR', has been defined to set the default colors to the current foreground and background colors for the rest of the session. o The intrinsic CALL FindF() now accepts an optional third argument, a string variable, to receive the absolute path of a file if it exists. Examples: Call FindF(Filename$,Status) Call FindF(Filename$,Status,ActualPathFound$) o Two new intrinsic functions have been implemented to convert binary variables to and from base-64 character strings. Example: Declare Intrinsic Function Base64$, Base64? String$ = Base64$(BinaryVariable?) Binary? = Base64?(StringVariable$) o Bug fixed: if a key in a SEARCH statement was specified with a subscripted string variable ("SEARCH #1,3,1;K$[1,10],R,S") and a key was successfully found, the new key value was not returned. o Bug fixed: the "mixedcase" option in the LUMAP and DL4LUST environment variables did not work and caused a syntax error. o Bug fixed: using double directory separators ("abc//def") in a path sometimes caused the MSC$(8xx) function to return an incorrect path. o Bug fixed: the DIR utility reported an illegal subscript error when it listed a FoxPro Full-ISAM file. Jul 19 2002 (Maintenance Release 5.1.1) o Behavior change: CALL MEMCOPY() now allows copy sizes that exceed the size of the destination variable if that variable is an element of a larger array or structure variable and the size is within the size of the surrounding variable. For example, it is possible to copy to multiple elements of an array starting at a specific subscript. o Behavior change: CALL IMSMEMCOPY() now prevents copying beyond the limits of the destination variable. If the destination variable is an array element or structure member, the limit is based on the entire array or structure variable. For example, it is possible to copy to multiple elements of an array starting at a specific subscript, but an attempt to copy beyond the end of the array will cause an error 38. o Bug fixed: on some platforms, dL4 5.1 could not be used with dynamicXport. Jul 10 2002 (Release 5.1) o Platform 99 software is now compiled for SCO OpenServer 5 rather than for SCO Unix 3.2.4. It is recommended that anyone using SCO Unix 3.2 upgrade to SCO OpenServer 5. o A new runtime parameter, DL4LUST, has been implemented to provide a UniBasic LUST-like search path for data files. Like LIBSTRING and other dL4 path lists, DL4LUST is a space separated list of directories. If DL4LUST is defined and a file is opened or created with a relative path, dL4 will search each directory in the list and use the first directory in which the file is found as the root directory of the file. If the file is being created and the file does not exist in any of the directories, then the file will be created using the first directory in the list. If the runtime parameter DL4DEFLU is defined, then the search will be modified to try each of the directories in DL4LUST first without and then with the value of DL4DEFLU appended. Example: Assume DL4LUST is equal to ". /usr/data test" DL4DEFLU is equal to "5" the current directory is "/home/fred/" then the statement OPEN #1,"file" would try to open "file" using the following paths and in the following order: ./file ./5/file /usr/data/file /usr/data/5/file /home/fred/test/file /home/fred/test/5/file The DL4LUST and LUMAP runtime parameters can both be defined and LUMAP mapping will be used instead of DL4LUST if an LUMAP mapping is found. In choosing between using DL4LUST and LUMAP, the UniBasic compatibility of DL4LUST should be weighed against the higher efficiency of LUMAP. In a networked file system environment, using LUMAP will avoid the high overhead of multiple directory searches over the network. o Behavior change from earlier beta release: if the runtime parameter DL4DEFLU is defined and a file is built without specifying a directory, then the file will be built in the DL4DEFLU specified directory in the first DL4LUST directory. If DL4LUST is not defined, then the file will be built in the DL4DEFLU directory under the current directory. An error will occur if the DL4DEFLU directory does not exist. o The LUMAP and DL4LUST runtime parameters can now accept filename options to control the legal character set for filenames and paths. The options are specified in parentheses at the beginning of the LUMAP or DL4LUST parameter string. The following options are recognized: "mixedcase" - do not convert the filename to lowercase (Unix) or uppercase (Windows) "unibasic" - limit the filename to letters, digits, "-", and ".". Ignore any character at and following an illegal character. "pfchar=x" - limit the filename as described for "unibasic" but convert the first "@" character to "x" and then ignore any following characters. If both LUMAP and DL4LUST are used, only one parameter string to specify the options or both strings must specify the same options. These options have no effect on absolute paths which are always used as given. o The LUMAP and DL4LUST runtime parameters can now accept a "case=" option to control case conversion in relative paths. By default, dL4 for Unix converts relative paths to lowercase Unix filenames when creating or opening files. Similarly, it converts lowercase Unix filenames to uppercase when CHF$(8xx) or other functions are used to retrieve the filename open on a channel. The "case=" option is specified in parentheses at the beginning of the LUMAP or DL4LUST parameter string. The values "" and "" in the "case=" argument must be replaced by the desired operating system ("") and user ("") case conversion: "l" - Convert to lowercase "u" - Convert to uppercase "a" - Leave case unchanged For example, an LUMAP value of "(case=la)" would perform the normal conversion of relative filenames to lowercase when creating or opening files, but it would always return the actual case of filenames in the CHF$(8xx) function. o The LUMAP and DL4LUST runtime parameters now support a "CHARSET=name" option to select the file system character set under Unix. The character set name must be either "ASCII", "US-ASCII", "ANSI", "ISO 8859-1", or "Windows". Example: LUMAP="(charset=ISO 8859-1)" export LUMAP The option can be set with or without setting a path mapping or search list. o The UniBasic utilities listed below have been converted to dL4. These are essentially the original UniBasic utilities loaded into dL4 using conversion profiles. The user interface and functionality are identical to that of the original UniBasic utilities. batch Execute commands on a phantom port bitsdir List directory contents (Unix only) change Change filename or attributes copy Copy files dokey Access or modify Indexed-Contiguous files format Create Formatted files keymaint Access or modify Indexed-Contiguous files libr List directory contents (Unix and Windows compatible) make Create files makecmnd Generate command files for BATCH or EXEC mfdel Delete files port Display port status or evict ports (the "term" utility is a native dL4 program that offers similar functions and extended dL4 options) scan Display file information who Display user information o Input cursor tracking is now supported with the new 'BTRACK' mnemonic. This feature is similar to UniBasic cursor tracking except that is enabled by outputting the 'BTRACK' mnemonic rather than an octal "\001\". The LOADSAVE "-c" and SCOPE CONVERT command will convert statements such as INPUT "\001\";A$ to INPUT 'BTRACK';A$ If a converted application uses PRINT statements to enable cursor tracking, the PRINT statements must be manually converted. o The translation of strings when reading from or writing to UniBasic or Universal files has been changed to support intrinsic CALLs that pack into or unpack data from strings. The new translation effects non-ASCII values which were previously translated to dL4 mnemonic codes. The new method translates any character in the mnemonic range to a special Unicode range of 0xf780 to 0xf7ff. This translation preserves the eight bit value of the translated characters allowing intrinsic packing CALLs to simply ignore the upper eight bits of the Unicode character. If characters in this special range are printed to a terminal or printer driver, the characters will be translated to actual dL4 mnemonic codes at output time. When writing to a UniBasic or Universal file, the special translation range, the standard dL4 mnemonics, and any Unicode character between 0x0080 and 0x00ff will all be translated to mnemonic character values. The purpose of this change is to ease conversion from UniBasic to dL4 by allowing access to files that contain packed data. The change will not be visible to existing dL4 applications if they simply read mnemonic values from file and print the values to a terminal, a printer, or another file. The change will be visible if the application examines the actual character values. For example, if an application reads mnemonic strings from a file and then compares the characters to dL4 mnemonics ('IF A$[I,I] = 'CS'), the characters will never be equal to the expected mnemonic characters. If your existing dL4 application depends on this type of behavior, please contact Dynamic Concepts. o The following intrinsic calls have been added for UniBasic compatibility: UniBasic CALL New equivalent dL4 Intrinsic CALL $ATOE Call AToE() CALL $CKSUM Call Cksum() CALL $CLU Call CLU() CALL $DATE Call Date() CALL $DEVOPEN Call DevOpen() CALL $DEVCLOSE Call DevClose() CALL $DEVREAD Call DevRead() CALL $DEVWRITE Call DevWrite() CALL $DEVPRINT Call DevPrint() CALL $ETOA Call EToA() CALL $LOCK Call Lock() CALL $MEMCMP Call MemCmp() CALL $RDFHD (97) Call Rdfhd() CALL $VOLLINK (91) Call VolLink() CALL 1 Call StrSrch1() CALL 5 Call MemCopy() CALL 7 Call SetEcho() CALL 15 Call PkUnPkDec() CALL 18 Call PkRdx5018() CALL 19 Call UnPkRdx5019() CALL 20 Call PkDec20() CALL 21 Call UnPkDec21() CALL 29 Call EditField() CALL 30 Call CopyStr() CALL 40 Call InitErrMsg() CALL 44 Call StrSrch44() CALL 45 Call PkDec45() CALL 46 Call UnPkDec46() CALL 47 Call Misc47() CALL 48 Call PkRdx5048() CALL 49 Call UnPkRdx5049() CALL 53 Call ASC2EBCDIC() CALL 57 Call ClearStr() CALL 72 Call Gather() CALL 73 Call Scatter() CALL 81 Call StrSrch81() CALL 95 Call IRISOS95() CALL 116 Call CloseAll() CALL 117 Call AvailBlks() CALL 118 Call NextAvPort() CALL 127 Call FileInfo() In order to use these intrinsic CALLs, a DECLARE INTRINSIC SUB statement must be used to declare the intrinsic SUB. A DECLARE statement will be added automatically when programs are converted using a conversion profile. o UniBasic CALL $MONITOR has been added to tools/oldcalls.lib, a dL4 library. This is a partial implementation that does not support returning the full list of open channels. The implementation is sufficient to support user status displays and it is used by the converted UniBasic PORT utility in the tools/ directory. o A new intrinsic function, ErrMsg$(), has been implemented to replace references to the UniBasic ERM() function. The ErrMsg$() function is used with CALL InitErrMsg() to replace the error message facility provided by UniBasic ERM() function and CALL 40. The standard conversion profile will convert ERM() function usage to ErrMsg$() and add the required DECLARE INTRINSIC FUNCTION statement. o A new intrinsic function, UBMem(), has been implemented to satisfy references to the UniBasic MEM() function. Like the UniBasic MEM() function, UBMem() always returns zero. The standard conversion profile will convert MEM() function usage to UBMem() and add the required DECLARE INTRINSIC FUNCTION statement. o The intrinsic CALL BitsNumStr() has been extended to accept string variables as well as binary variables as arguments. This enhancement makes the BitsNumStr() compatible with UniBasic CALL 2. o A new intrinsic CALL, IMSMEMCOPY(), has been implemented to provide compatibility with CALL 90 in IMS BASIC. The syntax of CALL IMSMEMCOPY() is: Call IMSMemCopy(Destination, Source, ByteCount) where "Destination" is a variable of any type, "Source" is a variable of any type, and "ByteCount" is a numeric variable or expression. The CALL copies "ByteCount" bytes from the "Source" variable to the "Destination" Variable. If both "Destination" and "Source" are string variables or arrays, then "ByteCount" characters are copied. This CALL is dangerous and will corrupt memory if "ByteCount" exceeds the size of the destination variable. This is allowed so that "Destination" variable can be a subscripted array element identifying the start of a copy range. o A new intrinsic CALL, CHSTAT(), has been implemented to return current SWAP level information. The BASIC syntax of the CALL has several possible parameter lists: Call ChStat(SwapLevel, ParentLineNum, ParentName$) Call ChStat(SwapLevel, ParentName$, ParentLineNum) Call ChStat(SwapLevel, ParentName$) Call ChStat(ParentName$, SwapLevel, ParentLineNum) Call ChStat(ParentName$, SwapLevel) Call ChStat(ParentName$) Call ChStat(SwapLevel, ParentLineNum) Call ChStat(SwapLevel) where "SwapLevel" receives the current SWAP level number (zero if there are no SWAPs in progress), "ParentLineNum" receives the line number of the SWAP statement in the parent program (zero if none), and "ParentName$" receives the name of the parent program ("" if none). o A new intrinsic CALL, CALLSTAT(), has been implemented to return current CALL-by-filename level information. The BASIC syntax of the CALL has several possible parameter lists: Call CallStat(CallLevel, ParentLineNum, ParentName$) Call CallStat(CallLevel, ParentName$, ParentLineNum) Call CallStat(CallLevel, ParentName$) Call CallStat(ParentName$, CallLevel, ParentLineNum) Call CallStat(ParentName$, CallLevel) Call CallStat(ParentName$) Call CallStat(CallLevel, ParentLineNum) Call CallStat(CallLevel) where "CallLevel" receives the current CALL-by-filename level number (zero if there are no CALLs-by-filename in progress), "ParentLineNum" receives the line number of the CALL statement in the parent program (zero if none), and "ParentName$" receives the name of the parent program ("" if none). o A new intrinsic function, CRC16(), has been implemented to calculate 16 bit CRC values. BASIC syntax: x = CRC16(mode, polynomial, string, oldcrc) where: "mode = 0" - calculate 8-bit sum of lower 8 bits of each character "mode = 1" - calculate CRC using lower 8 bits of each character An XMODEM compatible CRC can be calculated using mode one, a polynomial value of 4129 (0x1021), and an initial CRC of zero. o Enhancement: CALL ENV() now uses less memory if the same environment variable is set repeatedly. o Enhancement: the intrinsic CALLs SETGLOBALS() and GETGLOBALS() now support up to 1000 items (the previous default limit was 30). o A new option, "STRINGS HAGEN", has been added to provide compatibility with UniBasic HAGEN string mode. Example: OPTION DEFAULT STRINGS HAGEN o A new option, "ZERO DIVIDED BY ZERO IS LEGAL", has been added to make zero divided by zero equal to zero rather than causing an arithmetic overflow error. This option is also enabled by the "DIALECT IRIS1" and "DIALECT BITS1" options. Example: 10 Option Default Zero Divided By Zero Is Legal 20 Print 0 / 0 o A new option, "DIALECT IRIS1", has been added to provide a higher degree of IRIS compatibility than "DIALECT IRIS". The new option enables the "ZERO DIVIDED BY ZERO" option in addition to the other "DIALECT IRIS" options. o A new option, "DIALECT BITS1", has been added to provide a higher degree of BITS compatibility than "DIALECT BITS". The new option enables the "DIALECT BITS" options and also enables BITS style FOR/NEXT final value behavior, BITS USING mask features, and an initial precision of 4%. o A new option, "OPTION DIALECT IMS", has implemented to select IMS BASIC compatible behavior. That behavior is identical to "OPTION DIALECT IRIS1" except for USING mask behavior where a positive value is allowed to use all characters for digits. For example, the mask "--#.##" normally would generate an overflow result for 123.45, but outputs "123.45" with "OPTION DIALECT IMS". o Behavior change: "OPTION DIALECT IRIS1", "OPTION DIALECT BITS1", and "OPTION DIALECT IMS" now allow intrinsic CALLs and functions to return values in parameters even when the parameter is a subscripted string. This change improves compatibility with UniBasic and IMS BASIC. o A new option, 'PROGRAM TAG "text"' has been added to place user defined text in a program file as ASCII text. This option can be used to add revision text strings to be printed by the Unix "what" utility. Example: OPTION PROGRAM TAG "@(#) Test program 1.3" o A new option, "OPTION DEFAULT ARGUMENT CHECKING IS WEAK", has been added to support passing array variables to subprograms (CALL by filename) without using the empty bracket notation ('CALL "pgm",A[]'). This option improves compatibility with IMS BASIC. o The conversion profile format has been extended to automatically append "[]" to intrinsic CALL array parameters when a program is converted. For each intrinsic CALL that has array parameters, a prototype parameter list must be added to the conversion profile. For example, the following entry in the "[Intrinsic]" section of the standard tools/convert.prf file specifies that the second and the optional fifth parameters are arrays: FileInfo=127(Dir$,Info[],Filename$,Mode,DirInfo[]) Note that "[]" has been placed after each array parameter to inform dL4 that brackets should be added to these parameters during conversion. Using this information, the line CALL 127,D$,A,A$,1,T would be converted to Call FileInfo(D$,A[],A$,1,T[]) In this release, the types and names of the parameters in the conversion profile are not used during conversion and they do not need to match actual usage. o A new optional section, "[CallByFilename]", has been added to conversion profiles to append "[]" to each array parameter in a CALL-by-filename or in the ENTER statements of a subprogram that uses array parameters. This feature is used to convert from IMS BASIC and it is not needed when converting from UniBasic, IRIS, or BITS BASIC. For each subprogram that uses array parameters, an entry as shown below should be added to the "[CallByFilename]" section: [CallByFilename]" PrintReport="PrintReport"(A,B,C[],D) The example above would add "[]" to the third parameter of CALL "PrintReport" statement in each converted program. It would also add "[]" to the third parameter of the ENTER statement in "PrintReport" when converting that subprogram. The quoted filename in the conversion profile is case insensitive, but it must otherwise match the filename used in CALL statements. Synonyms may be added after the first filename for alternative forms. Example: PrintReport="PrintReport"(A,B,C[],D),"1/PrintReport" o A new optional setting has been defined for conversion profiles to convert references to undefined user functions ("FNx"). Without this option, undefined functions are treated as compile time errors and the program cannot be executed until the error is corrected. When enabled, the option adds definitions for each undefined function to the end of the program. The functions will generate an error 30 if used. Using the option the following program 10 Def Fna(x) = x + 5 20 Print Fna(3) + Fnb(4) would be converted to 1 Declare Function Fnb, Fnc 10 Def Fna(X) = X + 5 20 Print Fna(3) + Fnb(4) + Fnc(8) 1000 ! Dummy functions inserted for referenced, but undefined, functions 1001 External Function UndefinedFunctionError() 1002 Error 30 1003 End Function 0 1004 Def Fnb(X) = UndefinedFunctionError() 1005 Def Fnc(X) = UndefinedFunctionError() The line numbers used by the inserted lines are always greater than any line number used in the program. The option is enabled by adding a "ConvertUndefinedFunctions=True" line in the conversion profile settings section. Example: [Settings] ConvertUndefinedFunctions=True o A new optional setting has been defined for conversion profiles to convert references to undefined line numbers to labels and then add labeled statements at the end of the program. Using this option the following program 10 Print "Hello" \ Goto 30 20 Goto 1000 30 Print " world" would be converted to 10 Print "Hello" \ Goto 30 20 Goto U01000 30 Print " world" 1000 End ! Labels inserted for non-existent lines/labels 1001 U01000: Error 6 The line numbers used by the inserted labels are always greater than any line number used in the program. The option is enabled by adding a "ConvertUndefinedLineRefs=True" line in the conversion profile settings section. Example: [Settings] ConvertUndefinedLineRefs=True o A new optional setting has been defined for conversion profiles to renumber programs when they are converted. This option can be used when converting programs that need to have DECLARE INTRINSIC SUB and other statements inserted prior to the first line of program, but the first line has a line number of one. The following example would renumber a converted program to start at line 100 and increment by 10 for all following lines: [Settings] Renumber=100,10 o A new optional setting has been defined for conversion profiles to report each occurrence of a undefined intrinsic CALL as an error. [Settings] ReportUndefinedProcedures=True o If "Language=BITS" is specified in the "[Settings]" section of the conversion profile, "IF ERR 0" statements will be converted to "IF ERR(0)" statements. o If "Language=BITS" is specified in the "[Settings]" section of the conversion profile, "CHR(x)" will be converted to "CHR$(x)" in converted programs. o A new optional section, "[Edit]", has been added to conversion profiles to support user defined source editing that will be applied to each source line when a program source file is converted. The feature is available from both the LOADSAVE "-c profile" option and the SCOPE CONVERT command. The entries in the "[Edit]" section consist of pairs of lines where the first line defines what is to be replaced and the second line defines the new text. For example, if a conversion profile included the lines [Edit] OldText=Hello New=GoodBye then each occurrence of "Hello" in a source line would be replaced with "GoodBye". The keyword in the first line defines how the search will be performed: OldText= finds and replaces each exact match of the specified text OldTextCI= finds and replaces each case-insensitive match of the specified text OldTokens= finds and replaces each matching token string ignoring case and whitespace. It will NOT change text in string literals, mnemonic literals, DATA statements, or comments. A number in the text will match any equivalent numeric value ("1.3 will match with "1.30"). Because case and whitespace are ignored, the text "A + B" would match "a + b", "A+B", "A+b", and several other forms. Because this a token oriented search, "A + B" would not match "A + B1". OldString= finds and replaces each exact match of the specified text within a string literal ("abc") other than those in DATA statements OldMnemonic= finds and replaces each case-insensitive match of the specified text within a mnemonic literal ('CS BD') OldData= finds and replaces each exact match of the specified text in a DATA statement OldComment= finds and replaces each exact match of the specified text in a comment (! or REM) The keyword value is case insensitive in both the "old" and "new" lines. Example: [Edit] oldtokens=@0,23; new=@0,Msc(34); o A new boolean parameter, "ConvertCHF800To1300", has been added to the "[Settings]" section of the conversion profile. If set to "TRUE", "CHF(8xx)" function calls in the source program will be converted to "CHF$(13xx)" function calls which return the native absolute path. o When converting programs using "LOADSAVE -C" or the SCOPE CONVERT command, DECLARE statements are now added for DEF FN functions that are used prior to their declaration. The inserted DECLARE statements eliminates compile time errors that would otherwise be reported and allows the converted program to run. o When converting programs using "LOADSAVE -C" or the SCOPE CONVERT command, "CHF(e)" functions will be converted to "CHF$(e)" if "e" contains a constant between 800 and 899. o The SCOPE CONVERT command and the LOADSAVE "-c" convert option will now convert DATA statements by making each DATA value a quoted string. The READ statement has been enhanced to allow READing a DATA string value into a numeric value. o Conversion of DATA statements in IMS BASIC programs has been improved to accept end of line comments. This feature requires using a conversion profile with a "Language=IMS" setting. o The TERM utility in the Tools/ directory now has a DUMP option to request a program dump on a specified port. The DUMP option can only be used if the specified port has the DL4PORTDUMP environment variable defined to specify the dump file location. Example: #term 5 dump o The CHECKSUM utility in the Tools/ directory now has a "-c checksum" option to calculate a file checksum and compare the result to an expected value. o A new statement, CHAIN READ IF, has been added to perform a CHAIN READ of specified variables, but without reporting an error if any of the variables weren't passed by CHAIN WRITE statements. Example: CHAIN READ IF SubTotal, Filename$ o When used with DynamicXport, dL4 now supports using "dl4l()" or "dl4t()" references within "dl4c(For)" structures in template files. The "dl4c" format has been extended to supported the format "dl4c(For,)" and "dl4c(For,=)" to allow "dl4v()" references to the current array index number. o The run utility now returns an "unsuccessful" exit status to the operating system if a program exits with a STOP statement. o If an OPEN statement uses a "$" (output pipe) or "$$" (input pipe) filename to open a script, then the name of the current program will be passed to the script in the environment variable "DL4PROGRAM". The script can then use the program name to control printer spooling or special handling. o A new setting, "StaleReadAllowed=True", is now supported in the file section of a bridge profile. This setting enables re-reading the current record data after the record has been unlocked. Use of this setting is not recommended because the actual data record may have been changed and the old data will be used for any re-read operations. This feature is provided for compatibility with programs that performed such reads on Indexed-Contiguous files and already suffered from potential inconsistent data. o A UniBasic compatible PORTS runtime parameter has been implemented to set a user's port number according to the user's terminal name. By default, dL4 for Unix tries to use the numeric portion of the terminal name as the port number. For example, a user logged in on /dev/tty14 will try to use port number 14 if it is available (and assuming the PORT runtime variable isn't set to explicitly select the port number). The PORTS runtime parameter makes it possible to select which port number is used with a terminal name. The PORTS value is a list of colon separated terminal names where the first terminal name is port 0, the second name is port 1, and so on. If the specified terminal name contains an asterisk ("*"), a wildcard match will be performed and, if a match occurs, the current port number plus any number from within the wildcard portion will be the port number. If a name begins with a pound sign ("#"), the number following the pound sign is used to set the current port number for any subsequent terminal names. A name of "#any" will cause subsequent terminal names to use the highest available port number. o The PORT runtime parameter has been extended so that a value of "any" will cause the highest available port number to be used regardless of the terminal name. o A new runtime parameter, "MINPORT", has been defined to set the minimum port number to be used when automatically generating a port number. o A new runtime parameter, "AVAILREC", can be used to specify the value returned by SEARCH as the number the records available in indexed contiguous files. If the "AVAILREC" parameter is not set, the SEARCH statement will return, as it did in previous dL4 releases, the actual number of records available from the file free list or a minimum value of one. o A new runtime parameter, DL4DRIVERS, has been defined to configure dL4 driver selection. There are currently two DL4DRIVERS options, "Universal" and "ANSI Text". Setting DL4DRIVERS to "Universal" causes dL4 to create Universal Indexed-Contiguous or Formatted files by default instead of Portable Indexed-Contiguous or Formatted files. This can be useful if the files need to accessed by UniBasic or if mnemonics are to be stored in the files (note that only UniBasic supported mnemonics can be stored in Universal files). Setting DL4DRIVERS to "ANSI Text" causes dL4 to create and read text files using the ANSI (ISO 8859-1) character set instead of the UniBasic character set. Options in the DL4DRIVERS parameter are case-insensitive and multiple options can be separated by commas. Examples: DL4DRIVERS="Universal" DL4DRIVERS="universal,ansi text" o A new runtime parameter, DL4STOPDUMP, has been implemented to control whether a program dump should be written when a program exits via a STOP statement. If the environment variable DL4STOPDUMP is defined as an absolute path, then any program that exits via a STOP will cause a program dump file to be written to the path. The path can use the macro variables and other features of the DL4PORTDUMP runtime parameter. o A new MEMBER statement option has been added to specify variable length fields. The VARLEN option can be used with FoxPro Full-ISAM files to create memo fields instead of fixed length character fields. Example: Def Struct REC Member Name$[32] : Item "Name" Member 3%,Price : Item "Price" Member Comment$[100] : Item "Comment" : Varlen End Def The QUERY utility in the Tools/ directory displays variable length fields with a "V" attribute. o The DUPLICATE, KILL, and MODIFY statements now accept an option AS clause to specify the driver name or class. The AS clause is used with drivers that cannot be autoselected such as future SQL drivers. o The "Serial Terminal" and "Terminal Window" drivers now support output of zero bytes in binary output mode. o A new channel function, CHF(1500 + c), has been implemented to return the number of characters read by the last I/O operation. This channel function can be used when performing binary input from serial ports or sockets. o The "Data=XXX" open option to set serial line character size, parity, and stop bits has been extended to accept a question mark ("?") in place of the character size, parity, or number of stop bits. If "?" is used, then the existing value of that parameter will be left unchanged. Thus the option "Data=8?1" sets the character size to eight bits and the number of stop bits to one, but leaves the parity option unchanged. A new parity option, "P", has been defined to enable parity using the current even or odd parity setting. o To support conversion of IMS BASIC indexed contiguous files, a key translation feature has been added to dL4 Portable/Universal indexed contiguous files. The feature supports translating two digit years between "00" and "39" in keys to the values "An" through "Dn". This translation causes the keys for years 2000 - 2039 to be sorted correctly. An application using the file will only see numeric dates. The translation is defined for a file by using the statement Set #chan,-599;IndexNum,MapNum,Offset,Size where "IndexNum" is the index containing the keys to be translated, "MapNum" is the mapping function number (only function zero is supported), "Offset" is the zero based byte offset of the year in the key, and "Size" is the length of the key field in characters. The translation definition is stored in the file header and will be used by any subsequent open of the file. Key translation can be disabled on an open file by the statement "Set #chan,-599,0;" and re-enabled by the statement "Set #chan,-599,1;". The dL4 QUERY utility (tools/query) has been extended to display the translation option, if any, used by an index. o If a relative program path is used with the "run" utility, the native case-sensitive filename is tested in the search path before other possible paths. o