
                          DocMem 1.0  -  4/14/95

  /**********************************************************************/
  /**            Memory allocation bound checking routines.            **/
  /**  --------------------------------------------------------------  **/
  /**  Written and released into the public domain 1995 by Brian Reed  **/
  /**  (aka Doc Raster)  CIS 73503,3364 or 73503.3364@compuserve.com   **/
  /**  --------------------------------------------------------------  **/
  /**  Use at your own risk.                                           **/
  /**********************************************************************/


    DocMem is a replacement set of calls for use in debugging dynamic
    DOS memory allocations in your C programs.

    Currently, DocMem is a simplified system and may be too bulky or
    slow for larger applications.  The goal of DocMem is really only as a
    learning tool for myself, and as a help tool for those learning
    dynamic allocation techniques.

    To add DocMem to an existing application, you'll want to add a call
    to DOCstart() at the very beginning of your program, and a call to
    DOCend() at the end of your program.  Include DOCMEM.H in your
    application source code and compile/link DOCMEM.C in.

    Then use DOCfarmalloc() and DOCfarfree() on the allocations you
    wish to test, instead of farmalloc() and farfree().  When you free
    memory, DocMem checks that you have not exceeded the bounds of the
    allocation.  At any time, you may 'assert' pointer variables to assure
    they point to memory you've allocated, and that the memory has not
    been wildly over-written.

    Be sure to see the MAIN.C test file for examples of how to use DocMem,
    and the errors that it can detect.

    Before releasing code, you'll want to remove DocMem from your program,
    because the searching and testing will slow down your application.
    Alternatively, once you've tested your program you might make a macro
    that converts calls like DOCfarmalloc() to farmalloc().


    All feedback is appreciated!  If you wish to add to this utility,
    let me know and I'll get the latest source to you first.



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

                         FUNCTION REFERENCE

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    DOCstart()


    Prototype:

      void        DOCstart(void);


    Description:

      Start operation of the DocMem allocation system.  This must be
      used, and should appear at the very start of your program.


    Parameters:

      NONE


    Returns:

      NOTHING


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    DOCend()


    Prototype:

      int         DOCend(void);


    Description:

      Terminate operation of the DocMem allocation system.  Do this
      at the very end of your program.  If un-freed (hanging) memory
      allocations are found, these will automatically be asserted,
      then freed.


    Parameters:

      NONE


    Returns:

      If there are no un-freed allocations, returns DOC_OK, otherwise
      DOC_UNFREED is returned.


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    DOCfarmalloc()


    Prototype:

      void _far * DOCfarmalloc(unsigned long nbytes);


    Description:

      The replacement for farmalloc().  Used the same as farmalloc().


    Parameters:

      nbytes  = A long integer specifying bytes to allocate.


    Returns:

      On SUCCESS, a far pointer to the allocated memory.  On FAILURE,
      a NULL pointer.


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    DOCfarfree()


    Prototype:

      int         DOCfarfree(void _far *block);


    Description:

      The replacement for farfree().  Used the same as farfree().
      Before the memory is freed, it will be asserted as an
      integrity check.


    Parameters:

      A far pointer to the memory to be free'd.


    Returns:

      If successful, returns DOC_OK.  Otherwise, DOC_LOWADDR or
      DOC_INVALID will be returned.


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    DOCfarassert()


    Prototype:

      int         DOCfarassert(char *label, void _far *block);


    Description:

      This call 'asserts' a pointer.  If you give it an exact
      allocation base, it will check to see if the memory has
      been overwritten.  If you pass an arbitrary pointer, it
      will try to find what allocation it belongs to, then test
      that allocation for overwrite.


    Parameters:

      label = Text label to be output to DOCMEM.LOG for reference.

      block = The far pointer to assert.


    Returns:

      If the pointer points to memory you've allocated, and that
      memory is not over-written, then DOC_OK is returned.  If the
      pointer is invalid or the area is overwritten, the appropriate
      error is returned.  See DOCMEM.H for each error's value.


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    DOClog_write()


    Prototype:

      int         DOClog_write(char *label, int err, void _far *ptr)


    Description:

      Output a message to the logfile.  Normally this is used by
      DocMem itself, but you may call it to dump a label and pointer
      value to the log file.  For this, use DOC_USER as the err value.
      Note that printing a pointer this way does NOT assert it.



    Parameters:

      label = A user text string up to 20 characters long.

      err   = Specify DOC_USER to indicate this is a user log message.

      ptr   = A far pointer that will be be output to the log line.


    Returns:

      The value of the input argument 'err'.


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    DOCerr_string()


    Prototype:

      char      * DOCerr_string(int err);


    Description:

      Return a pointer to a string corresponding to the given error.


    Parameters:

      A DocMem error value.


    Returns:

      A string pointer.


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    DOCerr_last()


    Prototype:

      int         DOCerr_last(void);


    Description:

      Retrieve the last DocMem error value.


    Parameters:

      NONE


    Returns:

      The last DocMem error value.


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    DOCerr_set()


    Prototype:

      void        DOCerr_set(int err);


    Description:

      Set the DocMem error value.  most often used to clear the error
      value with DOC_OK.


    Parameters:

      The desired value to take place as the last error value


    Returns:

      NOTHING



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

                            ERROR MEANINGS

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    DOC_OK         0

      This value represents 'no error'.


    DOC_LOWADDR    1

      This means a pointer was used that has a suspiciously low
      value, like NULL (0).


    DOC_CORRUPT    2

      This message will appear when the memory of DocMem itself
      is over-written.


    DOC_INVALID    3

      The asserted pointer does not point within any area allocated
      using DocMem.


    DOC_OVERRUN    4

      The allocated memory has been exceeded at the top end.


    DOC_UNDERRUN   5

      The allocated memory has been exceeded at the low end.


    DOC_UNFREED    6

      This means that when DOCend() was called, memory that had been
      allocated by your program has not been freed.


    DOC_UNKNOWN    8

      The error is an unknown error number.



