#ifndef _NSRTRACE_ //-*-c++-*-
#define _NSRTRACE_

//----------------------------------------------------------------------
//  nsrLog.h
//   Provides Logging and Tracing facilities
//
//      Unpublished Confidential Information of Hewlett-Packard
//      Company. Do not disclose.  Copyright (c) Hewlett-Packard
//      Company 1995. All rights reserved
// 
// The contents of this software are proprietary and confidential to
// the Hewlett- Packard Company, and are limited in distribution to
// those with a direct need to know.  Individuals having access to
// this software are responsible for maintaining the confidentiality
// of the content and for keeping the software secure when not in use.
// Transfer to any party is strictly forbidden other than as expressly
// permitted in writing by Hewlett-Packard Company.  Unauthorized
// transfer to or possession by any unauthorized party may be a
// criminal offense.
//
//                  RESTRICTED RIGHTS LEGEND
//
//      Use,  duplication,  or disclosure by the U. S. Government is
//      subject to restrictions as set forth in subparagraph (c) (1)
//      (ii) in the Rights in Technical Data and Computer Software
//      clause in DFARS 252.227-7013 or any other successor clause.
//
//                      HEWLETT-PACKARD COMPANY
//                      3000 Hanover St.
//                      Palo Alto, CA  94304 U.S.A.
//
//      Rights for non-DOD U.S. Government Departments and Agencies
//      are as set forth in FAR 52.227-19 (c) (1,2) or any other
//      successor clause.
//
//  CLASSES:
//   Trace
//  
//----------------------------------------------------------------------
// $Source: /projects/HMS/nsr/udfCore/sys/nsrTrace.h,v $
// $Revision: 1.2 $     $Author: hmgr $
// $State: Exp $        $Locker:  $
// $Date: 96/05/21 15:09:50 $
//

//----------------------------------------------------------------------
// CLASS: Trace     --DVM
//
//  Used for Tracing execution, errors, and calls.
//
//  This object is used for providing trace output to a log file.
//  The log file may be set by the method logFile(). The output to it
//  may be specified to be any or all of the following:
//
//  Algorithm Tracing
//
//  This provides a static Boolean to be used by printf clauses
//  embedded in the paths of the code. Essentially, these points in
//  the code may simply invoke either the static Boolean
//  logAlgorithms() method, or the Boolean casting operator to see
//  whether this sort of tracing is enabled. In order to enable or
//  disable it, the static method call the static method
//  logAlgorithms() may be used.
//
//  Call Tracing
//
//  This also provides tracing output at construction and destruction
//  of a Trace object. Thus, if one is instantiated as the first order
//  of business in another method, its construction will be at the
//  time of method entry, and its destruction at the time of method
//  exit. Each instance of a Trace object must be provided with a
//  "tag", which should reflect the name of the scope just entered.
//  This is enabled or disabled via the static logCalls() method. 
//
//  Error Tracing
//
//  This also provides tracing output of error values at the time of
//  destruction (method exit). The error traced may be set statically
//  via the static defaultError() method, or may be overidden at
//  construction by providing a specific error variable to use. It is
//  enabled or disabled via the static logErrors() method.
//
// PUBLIC METHODS:
// Constructors:
//  Trace(String,err)  - Specifies tag and which error variable to
//                       trace. (Error is optional.)
// Static methods:
//  defaultError()     - sets or gets the default error to trace.
//  logFile()          - sets or gets logFile's FILE *
//  logErrors()        - sets or gets the logging of Errors.
//  logCalls()         - sets or gets the logging of Entry/Exit.
//  logAlgorithms()    - sets or gets the logging of misc traces.
//
// Non-static methods:
//  operator Boolean() - returns same as logAlgorithms().
//  tag()              - returns the tag.
//
// USAGE NOTES:
//  User notes go here.
// 
//----------------------------------------------------------------------
// COLLABORATORS:  
//  Contains one or more of the following objects:
//   Error
//   String
//   FILE *
//   Boolean
//
// PRIVATE METHODS:
//  methodName()
//      Description_of_method
//
// IMPLEMENTATION NOTES:
//  Internal Notes go here (special cases, algorithm issues, etc.)
//
//----------------------------------------------------------------------

class Trace 
{
    String         tag_           ;
    Error &        error_         ;
    static Error * defaultErrorp_ ;
    static FILE *  logFile_       ;
    static Boolean logErrors_     ;
    static Boolean logCalls_      ;
    static Boolean logAlgorithms_ ;
public:
    // Static setters
    static void defaultError(Error & err) {
        defaultErrorp_ = &err;
        return;
    }
    static void logFile(FILE * lf) {
        logFile_ = lf;
        return;
    }
    static void logErrors(Boolean le) {
        logErrors_ = le;
        return;
    }
    static void logCalls(Boolean lc) {
        logCalls_ = lc;
        return;
    }
    static void logAlgorithms(Boolean la) {
        logAlgorithms_ = la;
        return;
    }
    // Static getters
    static Error & defaultError(void) {
        return *defaultErrorp_;
    }
    static FILE * logFile(void) {
        return logFile_;
    }
    static Boolean logErrors(void) {
        return logErrors_ && logFile_ ? True : False;
    }
    static Boolean logCalls(void) {
        return logCalls_ && logFile_ ? True : False;
    }
    static Boolean logAlgorithms(void) {
        return logAlgorithms_ && logFile_ ? True : False;
    }
    // Non-static methods.
    String tag(void) {
        return tag_;
    }
    Trace(String tag) :
            tag_(tag),
            error_(*defaultErrorp_)
    {
        if (logCalls_) {
            fprintf(logFile_,">%s>\n",
                    (CONST_CHAR_PTR) tag_);
        }
    }
    Trace(String tag, Error & err) :
            tag_(tag),
            error_(err)
    {
        if (logCalls_) {
            fprintf(logFile_,">%s>\n",
                    (CONST_CHAR_PTR) tag_);
        }
    }
    ~Trace(void)
    {
        if (logErrors_) {
            if (error_) {
                fprintf(logFile_,">%s<--ERROR: %s\n",
                        (CONST_CHAR_PTR) tag_,
                        error_.message());
            }
        }
        if (logCalls_) {
            fprintf(logFile_,"<%s<\n",
                    (CONST_CHAR_PTR) tag_);
        }
        return;
    }
    operator Boolean(void)
    {
        return logAlgorithms_;
    }
};
    
#endif // _NSRTRACE_
