Dear CA-Clipper 5.2 Developer:

           Before applying the patch files for bringing your 
        CA-Clipper 5.2 product to the 5.2b level, you must first 
        determine the level you are currently at: 5.20 or 5.2a.   To 
        find out which level you are at, simply check the time stamp 
        on the CLIPPER.EXE that is installed on your system.  5.20 has 
        a timstamp of 5:20 AM.  5.2a has a time stamp of 5:21 AM.  The 
        level you are at determines which EXE file to use.  

           If you are currently at the 5.20 level, use the files from 
        52BUS.EXE to update the U.S. release, or 52BI.EXE for the 
        International release.  

           If you have already upgraded to 5.2a, use 52ABUS.EXE to 
        update the U.S. release, or 52ABI.EXE for the International 
        release.  

           If you attempt the patching process using the wrong files, 
        you will receive an error message indicating that the patch 
        will not work.  


================================================================================

        The problems resolved by CA-Clipper 5.2B include:


        1.     Fixed a Virtual Memory Integrity Failure in
               FOPEN() when the file name is numeric instead
               of a character string.

        2.     Fixed a Virtual Memory Integrity Failure when
               calling AADD() to increase the size of an
               array.

        3.     Fixed a Virtual Memory Integerity Failure
               that occured when an ACHOICE() user function
               deleted elements from the menu selection
               array.  ACHOICE() now allows the user
               function to add, delete, or modify existing
               elements without causing any problems in
               ACHOICE().

        4.     Fixed a Virtual Memory Integrity Failure in
               the Internal Runtime Event System.  This was
               causing the DBFCDX driver to hang as well as
               various "unexplainable" errors.

        5.     Fixed a Virtual Memory Integrity Failure in
               the debugger when viewing multiple nested
               arrays.  Tbrowse was producing a parameter
               error when viewing multiple nested arrays.
               In some instances this produced a Virtual
               Memory Integrity Failure.

        6.     Fixed a Virtual Memory Integrity Failure in
               the debugger's memory allocator.   (STAR
               Issue# 737689)

        7.     Fixed INDEXKEY() memory corruption problem.
               INDEXKEY() would occasionally return a
               garbage string when called repeatedly.  This
               sometimes caused a Virtual Memory Integrity
               Failure.

        8.     Fixed MEMOEDIT() buffer memory corruption
               problem.  This occurred when MEMOEDIT() was
               called with a user defined function.  This
               would result in various memory related errors
               including a Virtual Memory Integrity Failure.

        9.     Fixed slow disk I/O on replaces on large
               DBF's with non-unique indexes.  The
               performance has been improved to a speed
               which is comparable to CA-Clipper 5.01a.

       10.     Fixed the releasing of all relations (in all
               workareas) when any child dbf was closed.
               Now closing a child database releases only
               the relations that it is involved with.

       11.     Fixed the DBFNDX Replaceable Database Driver
               so that it now properly seeks on a date value
               with SET DELETED ON.

       12.     Fixed DBCREATE() to properly return a NIL
               value as documented.

       13.     Fixed INDEXORD() so that it now returns a
               zero when no database is open rather than
               generating a runtime error.

       14.     Fixed some occurances of internal error 1210
               (database and index are out of sync).

       15.     Fixed many occurances of internal error 415
               (can not open external overlay file).

       16.     Fixed the Runtime Memory Manager so that it
               now returns an EG_MEM (5300 "Memory Low
               Warning") before generating a memory
               exhausted error.

       17.     Fixed Runtime failures that occured when
               CA-Clipper mistakenly tried to use
               non-existent EMS memory.

       18.     Fixed FREAD() so that it does not modify
               variables that it shouldn't have access to.

       19.     Fixed BROWSE() so that it no longer
               causes the repositioning of a file to BOF()
               when editing takes place in a new record.

       20.     Fixed the debugger so that it is no longer
               necessary to specify the default file extension
               (.PRG or .PPO) when opening a file.

       21.     Fixed the debugger so that it correctly searches
               the path (indicated by the PATH environment variable)
               when searching for a file to open.

       22.     Fixed the debugger so that it does not
               produce "Argument error +" when the F6 key is
               pressed to view databases.

       23.     Fixed DBU so it now correctly parses a
               file name that contained a drive letter and
               colon (:) but no backslash (\) (such as
               C:TEMP).

       24.     Fixed numerous bugs in the R.L. utility.

       25.     Fixed the compiler screen to include the
               missing /t and /z options in order to match
               the documented options.

       26.     Fixed the spelling of OrdDestory to
               OrdDestroy in STD.CH for the DELETE TAG
               command.

       27.     Fixed the "Guide to CA-Clipper" .NG file so
               that the Norton Guide engine may now be
               unloaded from memory.


================================================================================


        Technical Note: The Virtual Memory Integrity Failure Error Message


	        The Virtual Memory Integrity Failure error message
        (or VMIF for short) refers to a problem that is neither well 
        documented nor well understood.  In this technical note, we will
        explore what the VMIF message indicates, some of the common 
        reasons it occurs, and what measures to take if  you encounter 
        one.

	        CA-Clipper uses a virtual memory manager to allow 
        applications to access more strings, arrays, and objects than
        conventional memory would otherwise allow.  It accomplishes 
        this by swapping information to and from expanded memory or 
        disk as needed.  Each virtual data item (called a segment) has
        an entry in a descriptor table that maintains its current 
        location and length.  A segment's length can be up to 65,518 
        bytes, while its location may be conventional memory (resident),
        disk or EMS (non-resident).  When CA-Clipper receives a request
        for non-resident data, it always checks the segment's descriptor
        entry to ensure that it's length is non-zero.  Any descriptor 
        whose length is zero is, by definition, invalid because VM does
        not allow zero-byte segments.  Thus, a zero length segment is 
        interpreted as a corruption, and the VMIF error message is 
        displayed. 

	        Along with the VMIF message is a hexadecimal address that 
        indicates the address of the corrupted descriptor table element.
        This information may be useful to the CA-Clipper Technical 
        Support as well as the development staff.  C and Assembler 
        programmers may also find this information useful in determining
        if and how their code caused the corruption.  A special case is
        the address 0000:0000.  It indicates that a NULL and (possibly
        uninitialized) pointer was used to access virtual data.

	        While it is true that the VMIF message occurs for
        exactly one condition, that condition can be created in many 
        different ways.  Research indicates that the conditions that 
        lead to a VMIF can be broken down into three distinct 
        categories.

	        First, several VMIFs can be attributed to Clipper 
        programming bugs.  While a VMIF should never occur solely on 
        the basis of executing Clipper code, a combination of inadequate
        error detection on the part of Clipper runtime and a violation
        of proper programming practices may cause the error to occur.  
        Examples of this have been: calling FOPEN() with numeric data 
        for the file name, deleting array elements from within an 
        ACHOICE() UDF, and assigning NIL to any TBROWSE instance 
        variable that requires a character value.  (Please note that 
        the TBROWSE VMIFs were fixed in the 5.01a release and the 
        ACHOICE() and FOPEN() VMIFs are fixed in the 5.2b release by 
        producing an error when improper values are used.)

	        The second category is within the CA-Clipper runtime 
        support libraries.  CA-Clipper's runtime support libraries 
        constantly issue calls to the VM system throughout the normal 
        execution of a Clipper application.  On occasion, specific 
        conditions pertaining to runtime activities are not properly 
        handled internally, creating conditions that eventually result 
        in a VMIF.  These instances are always considered problems by 
        the development staff.

	        The last category is external code typically written in
        C or Assembler by CA-Clipper programmers and third party library
        developers.  These are usually caused by improper use of one of
        CA-Clipper's APIs or by changing the functionality of something 
        within CA-Clipper's runtime that is assumed to remain constant.

	        Although CA-Clipper's VM system provides detection and 
        reporting, it is almost never the cause of a VMIF.

	        VMIFs are commonly detected long after the actual 
        corruption occurred.  A module may store a zero-length segment 
        in the segment descriptor table either through use of VM or by
        writing to a wild pointer.  This corruption will not be detected
        until a VM segment is accessed that requires the corrupted 
        segment to be discarded, or swapped to disk or EMS.  The Clipper
        VM subsystem is demand-based.  This means that it only performs
        swapping when swapping is absolutely required.  If a VMIF 
        consistently occurs at a specific point in the execution of an 
        application, it is often not actually caused at this point.  It 
        tells us that a corruption has occurred, but has no means for 
        determining the cause of the corruption or when the corruption 
        actually occurred.

	        Because VMIFs are detected when the VM system attempts 
        to swap in memory, a change in the amount of conventional memory
        available when an application is executed changes the 
        possibility of the VMIF occurring.  When sufficient real memory
        is available, VM has no need to perform any swapping and any 
        possible VMIFs will not be detected.  When less real memory is 
        available to an application, the entire profile of swapping is 
        changed, and may prevent the VMIF from occurring in a constant 
        location.

	        This raises the question of how to ensure that the VM 
        system is being called during the testing phase of application 
        development.  A simple and effective method is to use 
        CA-Clipper's //X: parameter to decrease the available memory as 
        much as is feasible.  This will ensure that the VM system will 
        be called with the most frequency.  (The //X: parameter is 
        detailed in the Runtime Environment chapter of the CA-Clipper 5.2 
        Programming and Utilities Guide.)

	        If a VMIF occurs, try to determine how to reproduce the 
        problem at will and if possible, isolate it to a small example 
        and immediately contact your CA-Clipper Technical Support 
        Representative.  The CA-Clipper Quality Assurance team is also 
        constantly searching for occurrences of VMIFs.  Either way, the 
        CA-Clipper Development team is anxious to correct all internal 
        VMIFs as quickly as possible.


================================================================================
================================================================================

