From e84e7821cdb29e794dece9df6f2dd97256a42f14 Mon Sep 17 00:00:00 2001 From: "warren%netscape.com" Date: Fri, 20 Oct 2000 01:14:47 +0000 Subject: [PATCH] Added new file - not in build yet. git-svn-id: svn://10.0.0.236/trunk@81497 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/xpcom/base/nslog.h | 215 +++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 mozilla/xpcom/base/nslog.h diff --git a/mozilla/xpcom/base/nslog.h b/mozilla/xpcom/base/nslog.h new file mode 100644 index 00000000000..624155b161b --- /dev/null +++ b/mozilla/xpcom/base/nslog.h @@ -0,0 +1,215 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#ifndef nslog_h__ +#define nslog_h__ + +/** + * LOGGING SERVICE + * + * We all know and love PR_LOG, but let's face it, it has some deficiencies: + * - can't direct output for different logs to different places, + * - isn't scriptable, + * - can't control printing format, including indentation, + * - it's ugly. + * We've solved these problems with NS_LOG, the new modern equivalent. Here's + * how you use it: + * + * #include "nslog.h" + * + * // First declare a new log: + * NS_IMPL_LOG(Foo) + * + * // Then define PRINTF and FLUSH routines for your log module: + * #define PRINTF NS_LOG_PRINT(Foo) + * #define FLUSH NS_LOG_FLUSH(Foo) + * + * void main() { + * // Then use it like this: + * PRINTF("hello world %d", 42); + * + * FLUSH(); // not necessary, but might be useful for synchronization + * } + * + * The above log statement will print something like this: + * + * a33e50 Foo hello world 42 + * + * The hex number at the beginning of the line indicates the ID of the thread + * executing the NS_LOG statement. The name of the log appears next. + * + * A cool feature of how these macros work is that when NS_DISABLE_LOGGING is + * defined, all the logging code macro-expands to nothing. + * + * You can also cause it to indent its output to help you log recursive execution: + * + * int fact(int n) { + * NS_LOG_WITH_INDENT(Foo, "fact"); + * PRINTF("calling fact of %d\n", n); + * if (n == 0) return 1; + * int result = n * fact(n - 1); + * PRINTF("fact of %d is %d\n", n, result); + * return result; + * } + * + * Calling fact(3) will produce a log that looks like this: + * + * 8e28b0 Foo [ Begin fact + * 8e28b0 Foo | calling fact of 3 + * 8e28b0 Foo | [ Begin fact + * 8e28b0 Foo | | calling fact of 2 + * 8e28b0 Foo | | [ Begin fact + * 8e28b0 Foo | | | calling fact of 1 + * 8e28b0 Foo | | | [ Begin fact + * 8e28b0 Foo | | | | calling fact of 0 + * 8e28b0 Foo | | | ] End fact + * 8e28b0 Foo | | | fact of 1 is 1 + * 8e28b0 Foo | | ] End fact + * 8e28b0 Foo | | fact of 2 is 2 + * 8e28b0 Foo | ] End fact + * 8e28b0 Foo | fact of 3 is 6 + * 8e28b0 Foo ] End fact + * + * If the second argument to NS_LOG_WITH_INDENT is nsnull, you don't get the + * Begin/End statements: + * + * 8e28b0 Foo | calling fact of 3 + * 8e28b0 Foo | | calling fact of 2 + * 8e28b0 Foo | | | calling fact of 1 + * 8e28b0 Foo | | | | calling fact of 0 + * 8e28b0 Foo | | | fact of 1 is 1 + * 8e28b0 Foo | | fact of 2 is 2 + * 8e28b0 Foo | fact of 3 is 6 + * + * You can control where the output of the log goes by setting its + * log event sink to an appropriate nsILogEventSink. By default the + * file log event sink does the following: + * - outputs to stderr + * - outputs to the platform's debug output for errors + * New log event sinks can be instantiated via the component manager: + * + * #ifdef NS_ENABLE_LOGGING + * nsComponentManager::CreateInstance(kFileLogEventSinkCID, + * nsnull, + * NS_GET_IID(nsIFileLogEventSink), + * &logEventSink); + * logEventSink->InitFromFILE("stdout", stdout); + * Foo->SetLogEventSink(logEventSink); + * #endif + * + * or the application can implement its own nsILogEventSink. + */ + +#include "prlog.h" // include prlog.h because we're going to override it's ancient macros +#include "nsDebug.h" +#include "nsILoggingService.h" +#include "nsCOMPtr.h" + +#if (defined(DEBUG) || defined(NS_DEBUG) || defined(FORCE_PR_LOG)) && !defined(WIN16) +// enable logging by default +#define NS_ENABLE_LOGGING +#endif + +#ifdef NS_DISABLE_LOGGING +// override, if you want DEBUG, but *not* logging (for some reason) +#undef NS_ENABLE_LOGGING +#endif + +#ifdef NS_ENABLE_LOGGING + +//////////////////////////////////////////////////////////////////////////////// + +PR_EXTERN(nsILog*) +NS_GetLog(const char* name, PRUint32 controlFlags = 0); + +//////////////////////////////////////////////////////////////////////////////// + +/** + * nsLogIndent: This class allows indentation to occur in a block scope. The + * automatic destructor takes care of resetting the indentation. Use the + * NS_LOG_WITH_INDENT macro. + */ +class NS_COM nsLogIndent +{ +public: + nsLogIndent(nsILog* log, const char* msg); + ~nsLogIndent(); + +protected: + nsILog* mLog; + const char* mHeaderMsg; +}; + +//////////////////////////////////////////////////////////////////////////////// +// macros + +#define NS_DECL_LOG(_log) \ + extern nsILog* _log; + +#define NS_IMPL_LOG(_log) \ + nsILog* _log = NS_GetLog(#_log); + +#define NS_IMPL_LOG_ENABLED(_log) \ + nsILog* _log = NS_GetLog(#_log, nsILog::DEFAULT_ENABLED); + +#define NS_LOG_ENABLED(_log) \ + ((_log) && (_log)->Test()) + +#define NS_LOG_PRINTF(_log) \ + (!NS_LOG_ENABLED(_log)) ? NS_OK : (_log)->Printf + +#define NS_LOG_FLUSH(_log) (_log)->Flush + +#define NS_LOG_WITH_INDENT(_log, _msg) nsLogIndent _indent_##_log(_log, _msg) +#define NS_LOG_BEGIN_INDENT(_log) ((_log)->IncreaseIndent()) +#define NS_LOG_END_INDENT(_log) ((_log)->DecreaseIndent()) + +#else // !NS_ENABLE_LOGGING + +inline void nsNoop(...) {} + +#define NS_DECL_LOG(_log) /* nothing */ +#define NS_IMPL_LOG(_log) /* nothing */ +#define NS_IMPL_LOG_ENABLED(_log) /* nothing */ +#define NS_LOG_ENABLED(_log) 0 +#define NS_LOG_PRINTF(_log) nsNoop +#define NS_LOG_FLUSH(_log) nsNoop +#define NS_LOG_WITH_INDENT(_log, _msg) ((void)0) +#define NS_LOG_BEGIN_INDENT(_log) ((void)0) +#define NS_LOG_END_INDENT(_log) ((void)0) + +#endif // !NS_ENABLE_LOGGING + +// Redefine NSPR's logging system: +#undef PR_LOG_TEST +#define PR_LOG_TEST(_log, _level) NS_LOG_ENABLED(_log) +#undef PR_LOG +#define PR_LOG(_log, _level, _args) NS_LOG_PRINTF(_log) _args +#define PRLogModuleInfo #error use_NS_DECL_LOG_instead +#define PR_NewLogModule #error use_NS_IMPL_LOG_instead +#undef PR_ASSERT +#define PR_ASSERT(x) NS_ASSERTION(x, #x) +#define printf use_NS_LOG_PRINTF_instead +#define fprintf use_NS_LOG_PRINTF_instead + +//////////////////////////////////////////////////////////////////////////////// +#endif // nslog_h__