TS Environment for Windows™ 

Dictionary-IV™ & Basic
Windows/NT Only
VMS Only
TS DataServer™
TS ORACLE DataServer™

UNIX Only (Ghost Task)
VMS Only
Windows Only

Thoroughbred Basic
8.5.0 Release Notes

Software Enhancements

General  [up]

  1. Additional performance for auto-expanding files.

  2. A new CVT string conversion replaces all unprintable characters with a space ($00$ - $1F$ and $7F$ - $FF$). For example:

    LET X$=CVT(Y$,16384)
  3. Re-writing an EXTRACTed record without specifying the KEY no longer requires exclusive control of the file.

  4. SET CTL allows a Basic program to assign a value to the Basic CTL variable.
    SET CTL 4
  5. A new directive SET TERM loads a Terminal Table from TCONFIG.
  6. Global PRM definitions can be defined in IPLPRM and can be used to store common PRM definitions for all users. PRMs that you might want to apply to an entire installation are CMASK SLEEPLOCK, IEEESWAP, and PUBLICS, however any PRM can be used globally.

    Note: A PRM that appears in both the global and individual (i.e. local) IPL files is processed as if both were local. The global is processed first so a local will override the global (when possible).

  7. The number of channels that may be open simultaneously is dynamic in 8.5 up to 1000. The CNF value is ignored unless it is greater than 1000 overriding the CNF value.

  8. Large file support is now also available for Linux Kernel Version 2.4 and Windows NT.

  9. DUMP VERSION will return the current Basic version information. From Basic console type in DUMP VERSION and press <CR>. It also works in run mode like other DUMP directives.

    The following is an example from a Linux system. Note: DUMP VERSION is supported by UNIX, Windows, and VMS Basic and will return similar information for both operating systems.


    Thoroughbred BASIC CLIENT Level 8.5.0r (10/10/01)
    Level 8.5 ADDON Feature: Journaling
    Computer: INTEL 386/486
    OS Name/Level: Red Hat 6.1 Linux 2.2.14-12

    ** END OF DUMP

  10. New Public Program debugging functionality has been added. Most of the console mode editing functionality can be applied to a stopped public program. Operations that caused an ERR=38 in previous versions are now allowed.

  11. A new PRM EDITPUBLICS has been added. When EDITPUBLICS is "on" an untrapped ESC key or an untrapped error will halt a public program at the current line in console mode. When EDITPUBLICS is "off" untrapped errors and the ESC key are reported as an error on the CALL statement.

    For example: If you get an ERROR 42 on a CALL statement and you know the problem is in the Public Program, you can use EDITPUBLICS. When you use this PRM while developing and testing, the Public Program will stop where the error occurred. You can then edit the program and save it.

  12. Added a new PRM CMASK to allow you to set the default values for CMASK for the entire session.

    PRM CMASK[=| ]"cmask_arg"

    cmask_arg is a two part field and must be enclosed in double quotes. The first character must be either a decimal point (.) or a comma (,) indicating the default to be used in numeric values. The remainder of the string is the value to be substituted for dollar signs. It can be from 1 to 8 characters in length. This PRM can be used with the TS ODBC DataServer and also in Basic. See SET CMASK in the Basic Language Reference (R-Z).

    PRM CMASK ","
    PRM CMASK "."
    SET CMASK ".=,"
    SET CMASK ".=.|$=$"
    SET CMASK ".=,|$=YEN"

  13. DUMP RETRY has been enhanced to display the last RETRY statement in each level of the call stack. Also, the LEVEL= option has been added to DUMP RETRY to allow specification of a particular environment level.

  14. Added the IOL() function

    For more information see item 5 below in Dictionary-IV & Basic.

  15. The REMOVE function no longer requires a KEY=value, if there is a record currently EXTRACTed.

Dictionary-IV™ & Basic  [up]

  1. New OPT for OPENs where Basic will maintain Dictionary-IV™ defined sorts.

    OPEN(ch,OPT="DLINK") "OELCUST" - all I/O to this channel (WRITE, REMOVE) will maintain all sort definitions defined for the Link "OELCUST". A REMOVE on this channel will also remove text field records for the specified key. Using this channel, records can be read in defined sort order using the SRT= option.

    A Source-IV™ example method UT.UTODLNK has been included in the 850 OPENworkshop® / IDOL-IV® distribution files. Please refer to this example source module for additional information on the OPT="DLINK" option. A source listing for UTODLNK is included in the appendix at the end of this document.

  2. %FORMAT, new alternate (or second) format data area.

    %format will have the same format properties as #format. This allows a second area to hold data and extend the use of format data names. It is a snap shot of the # format data area at a particular point in time. The %format must reference a valid #format. The %format must be included. The scope of the %format (as with #format) is global.


  3. FORMAT INCLUDE can now specify an ALIAS.

    This creates a second image of the format and the data area in memory. The alias option supports %formats. The alias name CANNOT exist in the dictionary. The format alias must be included. The scope of an alias format (as with #format) is global, however hard coded references to the alias can only be used in the program where the alias was defined. When referencing an alias outside of the program that defined it, you must use variables.

    Program "A"

    CALL "B"

    Program "B"

  4. A new option, ALIAS=, allows a link OPENed with OPT="LINK" or OPT="DLINK" to use a different format data area for I/O processing. For example:


  5. A new IOL() function allows data to be copied from a Basic IOLIST to a Format or a single string variable. Using a format definition:

    #format = IOL(30)

    The contents of each variable in the IOLIST is assigned, in sequence, to the data element names defined in the corresponding format definition. For example, format data element # 1 receives the contents of A$, format data element 2 receives the contents of B$, etc. Field separators defined in format must match the field separators in data file.

    The following snippets of example code illustrate using the #format=IOL(n) function to populate a format.

    00010 BEGIN
    00030 IOL=A$,B$,C,D$,E,F$,G$
    00100 READ(C)IOL=30
    00110 #UTCUST1=IOL(30)

    Using a string variable:


    The contents of each variable in the IOLIST is assigned, in sequence, to the string variable. Field separators are included in the string variable. This is similar to doing a READ RECORD when the data record contains field separators.

    The following snippets of example code illustrate using the string=IOL(n) function to populate a string variable.

    00010 BEGIN
    00030 IOL=A$,B$,C,D$,E,F$,G$
    00100 READ(C)IOL=30
    00110 RECORD$=IOL(30)
    00120 P=POS($8A$=RECORD$)
    00130 PRINT RECORD$(1,P-1)

UNIX Only  [up]

  1. XCALL is now available for HP_UX and AIX.

  2. The number of Ghost Tasks. has been expanded to 62. Ghost Ids of Ga – Gz are now valid.

  3. The ghoststat utility now supports a -e option to send an ESCAPE signal to a Ghost-task program. For example:
    ghoststat -e G0

Windows and NT Only  [up]

  1. The Window Basic can now function as an NT Service. Terminal emulation products can now Telnet to TS Environment for Windows. This is similar to the operation of a UNIX installation.

  2. If using TS DataServer, you can now place SERVER.MAP in your Windows System directory. If Basic does not find it in the current directory, it will search the system directory.

VMS Only  [up]

  1. The "TVMsort" file type, new for this release is a special form of MSORT file to allow the use of field-separated key data fields on VMS in a high speed RMS file instead of processing the file as a Tbred UNIX file. The file appears like a normal MSORT file to Basic™, however, on disk the data portion, i.e. the file with the .DAT extension is a native RMS multi-keyed file, with the key fields prepended to the Basic™ record. Although this requires more disk space for the same file, the benefit is 6 to 10 times faster processing.

    Creating this file type is done by using a sector number of -7 in the sector number of the MSORT directive or putting a 7 in the middle parameter of the PRM RMS record in the IPLINPUT file, e.g. PRM RMS 1,7,5

    In the above example of PRM RMS, when an MSORT with 0 in the sector number (the IDL4 and OPENworkshop® default) is executed, the second parameter is substituted in the sector number. Then the requested key structure is analyzed and

    • All key definitions are relative to field 0, AND
    • There are no mixed ascending/descending key segments in a key, AND
    • There are no more than 8 segments in any one key, THEN

      Create a native RMS multi-keyed file with the requested name; the sector number defaults back to 0.


    Create 2 files. The file with the requested name contains the key definition information, and filename.DAT is the native RMS file with key data prepended to the records. The key definition information remains in memory while the file is open so the key data of new and changed records can be extracted from the data and prepended before writing the records.

    Note: When using any MSORT files, please be aware that if you ADD or REMOVE sorts in a link, each one requires the entire key table to be rebuilt, and on VMS systems the file to be copied (the only way to rebuild the key table). The implication is that making a new file definition and copying the old file to the new, then renaming them can be much faster.

    Note: on VMS, if you take the FID of a file, the first 2 bytes will contain the following information: If byte-1 is "R" the file is an RMS file; if so byte 2 contains the special sector number used to create it, e.g. sector=dec(fid$(2,1)). Files created on VMS with -99 in the sector number will create Tbred Unix standard files. Use this to create a file that must be readable on Unix or Windows, just remember that -99 files are very slow on VMS.

TS DataServer™ Only  [up]

  1. Improved TS DataServer™ performance. Updates in this area include: packet compression, improvements in re-sync, and traffic reduction for file searches when contiguous IPL DEV lines reference the same data server ID.

TS ORACLE DataServer™ Only  [up]

  1. TS ORACLE DataServer™ interface has been updated to work with Basic large files.

OPT=DLINK Example  [up]

UTODLNK  - Example OPT=DLINK                          10/09/01 11:23:02   (1)
* Example Basic code using the 8.50 OPT=DLINK option.
* This example uses the Format UTCUST and the Link UTCUST.
* It requires that the sample data for UTCUST has been generated.
*    The option to Generate Sample Files is located on the System
*    Administration menu.
* The UTCUST Link defines:
*   Direct file UTCUST with a text field
*   Sort file UTCUSTsk with the following sorts:
*      Primary Sort: CUST-CODE
*             SORT1: CUST-NAME
*             SORT2: REP-CODE
*             SORT3: STATE
*             SORT4: ZIP-CODE
*             SORT5: YTD-SALES(D)

************** Working with Direct files and Sort files *********************
*  The secondary keys maintained in a sort file are composed of:
*      (1,1) Sort number 1 byte binary +
*      (2,n) data elements
* When a sort definition is defined with the C option (case sensitive), the
* case is preserved. The default is not case sensitive.
*  Case sensitive strings are stored as:
*        CVT(data-element,4096)
* On the WRITE, the Basic engine resolves the case based on the Link
* definition. On the READ of a secondary key, the data elements specified
* in KEY= must match the case defined for the sort or an ERR=11 will be
* returned.
* When a sort definition is defined with D option (descending order), the key
* value is adjusted force descending order.
*  Numeric descending fields are stored as:
*        NOT(STR(10000000+NUM(data-element):mask))
*  For example UTCUST SORT5 YTD-SALES(D) is adjusted as follows:
*        NOT(STR(10000000+NUM(E1$(118,10),NTP=1):"00000000.00"))
*  String descending fields are stored as:
*        NOT(data-element)
* On the WRITE, the Basic engine resolves the descending order based on the
* Link definition. On the READ of a secondary key, the data elements
* specified in KEY= must be match the descending order storage format or an
* ERR=11 returned.
************** Working with MSORT files **************************************
* MSORT and TISAM files follow the 'rules' as described in the Basic manual.
      WINDOW CREATE (80,24,0,0) "BORDER=LG";
      PRINT "Example OPEN with OPT=DLINK",'LF',
            "This example uses the data from the UTCUST examples",'LF',
            "If the sample data has not been generated please exit",'LF',
            "<cr> to run the example or <F4> quit";
      INPUT *;
      IF CTL=4
         GOTO CUEXIT
      FORMAT INCLUDE #UTCUST;          ! Include format for reads
      U=UNT;                           ! Get available channel

* The OPEN will use the Link name not the data file name. An OPEN statement
* for the sort file UTCUSTsk is not required.

      OPEN(U,OPT="DLINK")"UTCUST";     ! Open the LINK, not the data file.
* The KEY function with the SRT=n option will return the corresponding
* secondary key of the current key. This does not change the sort order or
* change the current key pointer.
      K$=KEY(U);                       ! Get current key: cust code "0001"
      READ(U);                         ! Advance key pointer for SORT0.
      K$=KEY(U,SRT="2");               ! Get corresponding key for SORT2:
                                       !    returns sales rep "003" +
                                       !            cust code "0001"
      K$=KEY(U);                       ! Get current key: cust code "0002"
* To establish a new sort order, perform a READ with the SRT=n option.
* This establishes the sort order for all subsequent READ and KEY functions.
      READ(U,SRT="2",KEY="",           ! Read to position the key pointer
                     ERC=99);          !  at the start of SORT2.
      K$=KEY(U);                       ! Get the first key for SORT2:
                                       !    returns sales rep "001" +
                                       !            cust code "0002"
      READ(U)#UTCUST;                  ! Read the corresponding data area and
                                       !    advance the key pointer.
* Change UTCUST.REP-CODE and update files.
* Only one WRITE statement using the primary key is required. On the WRITE
* statement the KEY= is not specified. If a KEY= was supplied, it would be
* ignored. ALL KEY VALUES are resolved by the Basic engine based on the
* Link definition. In addition, all secondary keys in UTCUSTsk are maintained
* for you by the Basic engine.
      #UTCUST.REP-CODE = "999";        ! Change the sales rep code.
      WRITE(U)#UTCUST;                 ! Write data back to the link.
                                       ! Both the data of the primary key
                                       !  is updated as well as ALL secondary
                                       !  keys in UTCUSTsk.
      K$=                              ! Build SORT2 key to read data:
         CHR(2)+                       !   sort nbr as 1 byte binary +
         #UTCUST.REP-CODE+             !   sales rep code +
         #UTCUST.CUST-CODE;            !   cust code
      FORMAT INIT #UTCUST;             ! Initialize data area.
      READ(U,KEY=K$)#UTCUST;           ! Read the data with new SORT2 key.
* Change current sort, set sort to SORT0
      READ(U,SRT="0",KEY="",ERC=99);   ! Read with new Sort number and
                                       !   position at start of SORT0.
      K$=KEY(U);                       ! Get the first key.
      READ(U)#UTCUST;                  ! Read the record.
* Change primary key: Add new record.
* All secondary keys are maintained for you, all the new secondary keys will
* be added to UTCUSTsk by the Basic engine.
     OLDKEY$=#UTCUST.CUST-CODE,       ! Save old key for delete
      #UTCUST.CUST-CODE="0000";        ! Change cust code
      WRITE(U) #UTCUST;                ! Write the new record to the link:
                                       !    do not use KEY=
      FORMAT INIT #UTCUST;             ! Initialize data area.
      READ(U,KEY="0000")#UTCUST;       ! Read data, current sort is SORT0.
      K$=KEY(U);                       ! Get next key.

 * Change sort order to SORT1
       READ(U,SRT="1",ERC=99);          ! Read with SRT= to establish SORT1.
                                       ! Build secondary key, this includes
                                       !  the sort number:
      K$=CHR(1)+                       !    sort number 1 byte binary +
         CVT(#UTCUST.CUST-NAME,4096)+  !    cust-name all lower case:
                                       !       (sort 1 is defined as not
                                       !        case sensitive) +
         #UTCUST.CUST-CODE;            !    cust-code.
      READ(U,KEY=K$)#UTCUST;           ! Read the corresponding data.
      K$=KEY(U);                       ! Get next key.

      READ(U,                          ! Read the link using sort 2,
         SRT="2",                      !   specify the sort and
         KEY=CHR(2)+                   !   supply the full
         #UTCUST.REP-CODE+             !   secondary sort
         #UTCUST.CUST-CODE)#UTCUST;    !   key.
      K$=KEY(U);                       ! Get next key

* Delete primary key. All secondary keys are maintained for you, all
* secondary keys will be removed from  UTCUSTsk by the Basic engine.
* NOTE: all corresponding text records will also be deleted. The REMOVE of
* a key is the only case where text records are managed by the Basic engine.

         REMOVE(U,KEY=OLDKEY$);        ! Remove the old primary key and all
                                       !  secondary keys and text records
                                       !  are removed by the Basic engine.
      PRINT "Example OPT=DLINK complete, <cr> to exit";
      INPUT *;

Software Changes

General  [up]

  1. =ALL option has been fixed to work outside IF statements. For example, PRINT "BLANK=",(A$=ALL "")

  2. False ERR=17 has been fixed when a disk directory DEV line was added as the last DEV line in IPLINPUT. Existing files could be accessed but attempts to create files would give the false error.

  3. A DUMP RETRY placed in a program beyond the first 64k would continue at random places after displaying the retry statement. This has been fixed.

  4. Problems using shell variables in IPLINPUT have been corrected, including variable $$ being deleted and unpredictable results when the last character of a line was $.

  5. Using IND= to read Auto Expanding files would return random data for non-existent records. ERR=2 is now issued as expected.

  6. Fractional powers 10**.25, 10**.5, and 10**.75 now give correct results.

  7. An ERASE with a rooted file name (name begins with "/") would erase files on a data server when no PREFIX directory was configured. This has been corrected so that a PREFIX data server directory is required before passing rooted file names to a data server.

  8. From a file OPENed with OPT=LINK, READing into a format other than the one specified in the link record now works properly.

  9. Problems with DUMP RETRY processing a multiple LET statement have been resolved.

  10. CVT() of a numeric data name now returns an ERR=20.

  11. On UNIX systems a disk full error was reported as ERR=103, TCB(3)=28. An ERR=15 is now produced.

  12. A time out problem that caused a 5 second delay when connecting to a data server has been fixed.

  13. When using XFD option 1 on a terminal with an internal name longer than 2 characters, the third and fourth characters are placed in positions 12 and 13 on the XFD string

  14. ENCRYPT and PSAVE will now LIST properly when PWD is included.

  15. OPEN FILES CACHING would fail with MSORT and TISAM files. This has been corrected.

  16. A problem that caused Linux clients to hang when a data server connection timed out has been corrected.

UNIX Only (Using Ghost Tasks)  [up]

  1. TSK(3) would fail with an error 33 when used in a Ghost Task. This has been corrected.
  2. Using a single quote to recall the last entered statement requires that channel 0 be open to a terminal. Attempting to use this feature while communicating with a Ghost Task is now ignored. Future releases of the *GPSD utility may include an internal statement recall for this purpose.

VMS Only  [up]

  1. A problem causing 2/.002 = 1 has been corrected.

  2. KEY() immediately after an OPEN of an MSORT file no longer returns the maximum key length. It returns the primary key length.

  3. Problems with FST(,1) processing a TISAM file have been resolved.

  4. FST() no longer returns an erroneous ERR=12 when processing a file name containing a "*".

  5. MSORT will create a TISAM file when a -99 is specified as the sector number.

  6. Basic™ now accepts a 4-character task id where the second character of the task id is a letter. For example, task id TT01.

  7. Problems with retrieving the DSD() of a server directory have been resolved.

Windows Only  [up]

  1. On Windows NT, a tiny font is no longer produced when printing to LPT via a type 3 printer.

  2. On Windows NT, character height and width problems have been resolved when printing via a type 3 printer.

  3. The AltGr key on international keyboards no longer prevents function key entry.

  4. The Euro symbol can now be input from an international keyboard. It will also be displayed properly when using a font that supports the Euro symbol.

Copyright ©2002 Thoroughbred Software International, Inc. Unauthorized uses is prohibited.