summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2010-05-11 14:12:42 +0200
committerLukas Zeller <luz@synthesis.ch>2010-05-13 14:08:48 +0200
commit7cb91dc4d56a7f09bb47109bd5e048a154ba1517 (patch)
treeff8e947d2763fb38612614012149c8b275db547a
parent8270832de3f15a3ab6abaaf9c3dc5c1d4f26b93e (diff)
Source-Linked Logs: record and link call location of debug messages in (HTML) log files
For someone unfamiliar with the source code, it is sometimes hard to locate the code which produced a certain message. This patch solves this issue like this: - produce a fully cross-referenced HTML version of the source with Doxygen - extend the logging functions and macros so that each message comes with file name, line number and function name information - turn the time stamp in the HTML output into a link to the source code line, with the function name as title The reason for picking the time stamp was that making other text a link would interfere with the visual markup of it (color, bold, etc.). In such an enriched log one can: - hover over the time stamp to see function name in a bubble help and the URL (and thus source code location) at the bottom of the browser window (at least in Firefox) - click on the time stamp to jump to the source code Because this feature makes both the library and the logs larger, it is turned off by default. Configure with --enable-debug-logs to enable it when using autotools. Macro tricks are used to produce the same code as before when the feature is off. Limitations: - Without time stamp logging, no links are recorded. - Each change in the Synthesis source code forces a complete new run of Doxygen. This makes compilation quite a bit slower, but the only alternative would be to accept that logs and source dump are inconsistent in the changed parts. - The links contain the absolute file path (making it a bit harder to share logs and source code dumps). - The TClientEngineInterface::debugPuts() API introduced for and used by SyncEvolution leads to links which contain the wrong absolute path to the Doxygen HTML files (inside libsynthesis instead of SyncEvolution). - The "prefix" parameter in that same API is still ignored.
-rw-r--r--src/DB_interfaces/api_db/pluginapiagent.cpp4
-rw-r--r--src/Doxyfile40
-rw-r--r--src/Makefile.am.in23
-rwxr-xr-xsrc/sysync/debuglogger.cpp156
-rwxr-xr-xsrc/sysync/debuglogger.h78
-rw-r--r--src/sysync/engineinterface.cpp2
-rwxr-xr-xsrc/sysync/syncappbase.cpp4
-rw-r--r--src/sysync/syncclientbase.cpp2
-rwxr-xr-xsrc/sysync/sysync_debug.h64
9 files changed, 243 insertions, 130 deletions
diff --git a/src/DB_interfaces/api_db/pluginapiagent.cpp b/src/DB_interfaces/api_db/pluginapiagent.cpp
index 81065b7..529a43a 100644
--- a/src/DB_interfaces/api_db/pluginapiagent.cpp
+++ b/src/DB_interfaces/api_db/pluginapiagent.cpp
@@ -54,7 +54,7 @@ extern "C" void SessionLogDebugBlock(void *aCallbackRef, const char *aTag, const
if (aCallbackRef) {
bool collapsed=false;
if (aTag && aTag[0]=='-') { aTag++; collapsed=true; }
- static_cast<TSyncSession *>(aCallbackRef)->getDbgLogger()->DebugOpenBlock(aTag,aDesc,collapsed,"%s",aAttrText);
+ static_cast<TSyncSession *>(aCallbackRef)->getDbgLogger()->DebugOpenBlock(TDBG_LOCATION_NONE aTag,aDesc,collapsed,"%s",aAttrText);
}
} // SessionLogDebugBlock
@@ -63,7 +63,7 @@ extern "C" void SessionLogDebugEndBlock(void *aCallbackRef, const char *aTag)
{
if (aCallbackRef) {
if (aTag && aTag[0]=='-') aTag++;
- static_cast<TSyncSession *>(aCallbackRef)->getDbgLogger()->DebugCloseBlock(aTag);
+ static_cast<TSyncSession *>(aCallbackRef)->getDbgLogger()->DebugCloseBlock(TDBG_LOCATION_NONE aTag);
}
} // SessionLogDebugEndBlock
diff --git a/src/Doxyfile b/src/Doxyfile
index 1eeea5e..f129552 100644
--- a/src/Doxyfile
+++ b/src/Doxyfile
@@ -25,7 +25,7 @@ DOXYFILE_ENCODING = UTF-8
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
-PROJECT_NAME =
+PROJECT_NAME = libsynthesis
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
@@ -221,7 +221,7 @@ OPTIMIZE_OUTPUT_VHDL = NO
# func(std::string) {}). This also make the inheritance and collaboration
# diagrams that involve STL classes more complete and accurate.
-BUILTIN_STL_SUPPORT = NO
+BUILTIN_STL_SUPPORT = YES
# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.
@@ -277,17 +277,17 @@ TYPEDEF_HIDES_STRUCT = NO
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-EXTRACT_ALL = NO
+EXTRACT_ALL = YES
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
-EXTRACT_PRIVATE = NO
+EXTRACT_PRIVATE = YES
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
-EXTRACT_STATIC = NO
+EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
@@ -308,7 +308,7 @@ EXTRACT_LOCAL_METHODS = NO
# name of the file that contains the anonymous namespace. By default
# anonymous namespace are hidden.
-EXTRACT_ANON_NSPACES = NO
+EXTRACT_ANON_NSPACES = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
@@ -450,7 +450,7 @@ SHOW_USED_FILES = YES
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
# in the documentation. The default is NO.
-SHOW_DIRECTORIES = NO
+SHOW_DIRECTORIES = YES
# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
# This will remove the Files entry from the Quick Index and from the
@@ -534,7 +534,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT =
+INPUT = $(INPUT)
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -557,7 +557,7 @@ FILE_PATTERNS =
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
-RECURSIVE = NO
+RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
@@ -647,7 +647,7 @@ FILTER_SOURCE_FILES = NO
# Note: To get rid of all source code in the generated output, make sure also
# VERBATIM_HEADERS is set to NO.
-SOURCE_BROWSER = NO
+SOURCE_BROWSER = YES
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
@@ -658,19 +658,19 @@ INLINE_SOURCES = NO
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
-STRIP_CODE_COMMENTS = YES
+STRIP_CODE_COMMENTS = NO
# If the REFERENCED_BY_RELATION tag is set to YES
# then for each documented function all documented
# functions referencing it will be listed.
-REFERENCED_BY_RELATION = NO
+REFERENCED_BY_RELATION = YES
# If the REFERENCES_RELATION tag is set to YES
# then for each documented function all documented entities
# called/used by that function will be listed.
-REFERENCES_RELATION = NO
+REFERENCES_RELATION = YES
# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
@@ -701,7 +701,7 @@ VERBATIM_HEADERS = YES
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
-ALPHABETICAL_INDEX = NO
+ALPHABETICAL_INDEX = YES
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
@@ -890,7 +890,7 @@ FORMULA_FONTSIZE = 10
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
-GENERATE_LATEX = YES
+GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
@@ -1141,7 +1141,7 @@ SEARCH_INCLUDES = YES
# contain include files that are not input files but should be processed by
# the preprocessor.
-INCLUDE_PATH =
+INCLUDE_PATH = $(INCLUDE_PATH)
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -1158,7 +1158,7 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED =
+PREDEFINED = $(PREDEFINED)
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
@@ -1199,7 +1199,7 @@ TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
-GENERATE_TAGFILE =
+GENERATE_TAGFILE = libsynthesis.tags
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
@@ -1251,7 +1251,7 @@ HIDE_UNDOC_RELATIONS = YES
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
-HAVE_DOT = NO
+HAVE_DOT = YES
# By default doxygen will write a font called FreeSans.ttf to the output
# directory and reference it in all dot files that doxygen generates. This
@@ -1393,7 +1393,7 @@ DOT_TRANSPARENT = YES
# makes dot run faster, but since only newer versions of dot (>1.8.10)
# support this, this feature is disabled by default.
-DOT_MULTI_TARGETS = NO
+DOT_MULTI_TARGETS = YES
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
# generate a legend page explaining the meaning of the various boxes and
diff --git a/src/Makefile.am.in b/src/Makefile.am.in
index fd6bac0..687bcdc 100644
--- a/src/Makefile.am.in
+++ b/src/Makefile.am.in
@@ -158,3 +158,26 @@ libsmltk_la_CXXFLAGS = $(libsmltk_la_CFLAGS)
libsmltk_la_LDFLAGS = -version-info $(ENGINE_CURRENT):$(ENGINE_REVISION):$(ENGINE_AGE) \
-Wl,--version-script=$(srcdir)/smltk-linker.map
libsmltk_la_DEPENDENCIES = $(srcdir)/smltk-linker.map
+
+# Doxygen for complete source code as used in autotools build.
+# The dependency on the libs ensures that doxygen is invoked
+# anew when any input file for those changes, reusing the
+# automatic dependency tracking. A side effect (both good
+# and bad) is that doxygen will not be invoked on code
+# which does not compile.
+html/index.html: Doxyfile libsynthesis.la libsynthesissdk.la
+ rm -rf html
+ INPUT="$(srcdir)/platform_adapters $(srcdir)/syncml_tk $(srcdir)/sysync_SDK $(srcdir)/sysync $(srcdir)/DB_interfaces" \
+ INCLUDE_PATH="$(srcdir)/Targets/ReleasedProducts/autotools $(srcdir)/Targets/ReleasedProducts/combiEngine_opensource_linux $(srcdir)/sysync_SDK/Sources" \
+ PREDEFINED="`cat $(srcdir)/Targets/ReleasedProducts/combiEngine_opensource_linux/target_options.h | grep '^#define' | grep '1 *$$' | sed -e 's/#define //' -e 's/ 1//'`" \
+ doxygen $<
+
+.PHONY: doxygen
+doxygen: html/index.html
+clean-doxygen:
+ rm -rf html
+
+if COND_DOXYGEN
+all: doxygen
+clean-local: clean-doxygen
+endif \ No newline at end of file
diff --git a/src/sysync/debuglogger.cpp b/src/sysync/debuglogger.cpp
index e093f8d..db43fda 100755
--- a/src/sysync/debuglogger.cpp
+++ b/src/sysync/debuglogger.cpp
@@ -510,7 +510,7 @@ void TDebugLoggerBase::outputVia(TDebugLoggerBase *aDebugLoggerP)
// output formatted text
-void TDebugLoggerBase::DebugVPrintf(uInt32 aDbgMask, cAppCharP aFormat, va_list aArgs)
+void TDebugLoggerBase::DebugVPrintf(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aFormat, va_list aArgs)
{
// we need a format and debug not completely off
if ((getMask() & aDbgMask)==aDbgMask && aFormat) {
@@ -520,7 +520,7 @@ void TDebugLoggerBase::DebugVPrintf(uInt32 aDbgMask, cAppCharP aFormat, va_list
// assemble the message string
vsnprintf(msg, maxmsglen, aFormat, aArgs);
// write the string
- DebugPuts(aDbgMask,msg);
+ DebugPuts(TDBG_LOCATION_ARG aDbgMask,msg);
}
} // TDebugLoggerBase::DebugVPrintf
@@ -534,13 +534,13 @@ TDebugLoggerBase &TDebugLoggerBase::setNextMask(uInt32 aDbgMask)
// like DebugPrintf(), but using mask previously set by setNextMask()
-void TDebugLoggerBase::DebugPrintfLastMask(cAppCharP aFormat, ...)
+void TDebugLoggerBase::DebugPrintfLastMask(TDBG_LOCATION_PROTO cAppCharP aFormat, ...)
{
va_list args;
// we need a format and debug not completely off
if ((getMask() & fNextDebugMask)==fNextDebugMask && aFormat) {
va_start(args, aFormat);
- DebugVPrintf(fNextDebugMask,aFormat,args);
+ DebugVPrintf(TDBG_LOCATION_ARG fNextDebugMask,aFormat,args);
va_end(args);
}
fNextDebugMask=0;
@@ -548,78 +548,129 @@ void TDebugLoggerBase::DebugPrintfLastMask(cAppCharP aFormat, ...)
// output formatted text
-void TDebugLoggerBase::DebugPrintf(uInt32 aDbgMask, cAppCharP aFormat, ...)
+void TDebugLoggerBase::DebugPrintf(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aFormat, ...)
{
va_list args;
// we need a format and debug not completely off
if ((getMask() & aDbgMask)==aDbgMask && aFormat) {
va_start(args, aFormat);
- DebugVPrintf(aDbgMask,aFormat,args);
+ DebugVPrintf(TDBG_LOCATION_ARG aDbgMask,aFormat,args);
va_end(args);
}
} // TDebugLoggerBase::DebugVPrintf
// open new Block without attribute list
-void TDebugLoggerBase::DebugOpenBlock(cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed)
+void TDebugLoggerBase::DebugOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed)
{
// we need a format and debug not completely off
if (getMask() && aBlockName) {
- DebugOpenBlock(aBlockName,aBlockTitle,aCollapsed,NULL);
+ DebugOpenBlock(TDBG_LOCATION_ARG aBlockName,aBlockTitle,aCollapsed,NULL);
}
} // TDebugLoggerBase::DebugOpenBlock
// open new Block with attribute list, printf style
-void TDebugLoggerBase::DebugOpenBlock(cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, ...)
+void TDebugLoggerBase::DebugOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, ...)
{
va_list args;
// we need a format and debug not completely off
if (getMask() && aBlockName) {
va_start(args, aBlockFmt);
- DebugVOpenBlock(aBlockName,aBlockTitle,aCollapsed,aBlockFmt,args);
+ DebugVOpenBlock(TDBG_LOCATION_ARG aBlockName,aBlockTitle,aCollapsed,aBlockFmt,args);
va_end(args);
}
} // TDebugLoggerBase::DebugOpenBlock
// open new Block with attribute list, printf style, expanded by default
-void TDebugLoggerBase::DebugOpenBlockExpanded(cAppCharP aBlockName, cAppCharP aBlockTitle, cAppCharP aBlockFmt, ...)
+void TDebugLoggerBase::DebugOpenBlockExpanded(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, cAppCharP aBlockFmt, ...)
{
va_list args;
// we need a format and debug not completely off
if (getMask() && aBlockName) {
va_start(args, aBlockFmt);
- DebugVOpenBlock(aBlockName,aBlockTitle,false,aBlockFmt,args);
+ DebugVOpenBlock(TDBG_LOCATION_ARG aBlockName,aBlockTitle,false,aBlockFmt,args);
va_end(args);
}
} // TDebugLoggerBase::DebugOpenBlockExpanded
// open new Block with attribute list, printf style, collapsed by default
-void TDebugLoggerBase::DebugOpenBlockCollapsed(cAppCharP aBlockName, cAppCharP aBlockTitle, cAppCharP aBlockFmt, ...)
+void TDebugLoggerBase::DebugOpenBlockCollapsed(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, cAppCharP aBlockFmt, ...)
{
va_list args;
// we need a format and debug not completely off
if (getMask() && aBlockName) {
va_start(args, aBlockFmt);
- DebugVOpenBlock(aBlockName,aBlockTitle,true,aBlockFmt,args);
+ DebugVOpenBlock(TDBG_LOCATION_ARG aBlockName,aBlockTitle,true,aBlockFmt,args);
va_end(args);
}
} // TDebugLoggerBase::DebugOpenBlockCollapsed
+#ifdef SYDEBUG_LOCATION
+/// turn text into link to source code
+static string TDbg2Link(const TDbgLocation &aTDbgLoc, const string &aTxt)
+{
+ if (!aTDbgLoc.fFile)
+ return aTxt;
+
+ string line;
+
+ line+="<a href=\"";
+ // replace path with path to Doxygen HTML pages,
+ // mangle base name like Doxygen does
+ line+=SYDEBUG_LOCATION;
+ line+="/";
+ string file = aTDbgLoc.fFile;
+ size_t off = file.rfind('/');
+ if (off != file.npos)
+ file = file.substr(off + 1);
+ for (off = 0; off < file.size(); off++) {
+ switch(file[off]) {
+ case '_':
+ line+="__";
+ break;
+ case '.':
+ line+="_8";
+ break;
+ default:
+ line+=file[off];
+ break;
+ }
+ }
+ StringObjAppendPrintf(line,"-source.html#l%05d",aTDbgLoc.fLine);
+ line+="\"";
+ if (aTDbgLoc.fFunction) {
+ line+=" title=\"";
+ line+=aTDbgLoc.fFunction;
+ line+="\"";
+ }
+ line+=">";
+ line+=aTxt;
+ line+="</a>";
+
+ return line;
+}
+#else
+static string TDbg2Link(const string &aTxt)
+{
+ return aTxt;
+}
+#endif
+
// output text to debug channel
-void TDebugLoggerBase::DebugPuts(uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize, bool aPreFormatted)
+void TDebugLoggerBase::DebugPuts(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize, bool aPreFormatted)
{
// we need a text and debug not completely off
if (!((getMask() & aDbgMask)==aDbgMask && aText && fDbgOptionsP)) {
// cannot output
//#ifdef __MWERKS__
//#warning "ugly hack"
- DebugPutLine("<li><span class=\"error\">Warning: Dbg output system already half shut down (limited formatting)!</span></li><li>");
- if (aText) DebugPutLine(aText);
- DebugPutLine("</li>");
+ DebugPutLine(TDBG_LOCATION_NONE "<li><span class=\"error\">Warning: Dbg output system already half shut down (limited formatting)!</span></li><li>");
+ if (aText) DebugPutLine(TDBG_LOCATION_NONE aText);
+ DebugPutLine(TDBG_LOCATION_NONE "</li>");
//#endif
}
else {
@@ -659,18 +710,21 @@ void TDebugLoggerBase::DebugPuts(uInt32 aDbgMask, cAppCharP aText, stringSize aT
line="<li>";
// add timestamp if needed for every line
if (fDbgOptionsP->fTimestampForAll || fDbgOptionsP->fThreadIDForAll) {
- line+="<i>[";
+ string prefix;
+ prefix+="<i>[";
#ifdef MULTI_THREAD_SUPPORT
if (fDbgOptionsP->fThreadIDForAll) {
- StringObjAppendPrintf(line,"%09lu",myThreadID());
- if (fDbgOptionsP->fTimestampForAll) line+=", ";
+ StringObjAppendPrintf(prefix,"%09lu",myThreadID());
+ if (fDbgOptionsP->fTimestampForAll) prefix+=", ";
}
#endif
if (fDbgOptionsP->fTimestampForAll) {
StringObjTimestamp(ts,getSystemNowAs(TCTX_SYSTEM));
- line+=ts;
+ prefix+=ts;
}
- line+="]</i>&nbsp;";
+ prefix+="]</i>&nbsp;";
+
+ line+=TDbg2Link(TDBG_LOCATION_ARG prefix);
}
// colorize some messages
string cl="";
@@ -749,7 +803,7 @@ void TDebugLoggerBase::DebugPuts(uInt32 aDbgMask, cAppCharP aText, stringSize aT
line+=ts;
line+="</time>";
}
- DebugPutLine(line.c_str(),line.size());
+ DebugPutLine(TDBG_LOCATION_NONE line.c_str(),line.size());
line.erase();
}
if (fDbgOptionsP->fSeparateMsgs) {
@@ -868,7 +922,7 @@ void TDebugLoggerBase::DebugPuts(uInt32 aDbgMask, cAppCharP aText, stringSize aT
}
line+="</li>"; // we need to close the list entry
}
- DebugPutLine(line.c_str(),line.size(),pre);
+ DebugPutLine(TDBG_LOCATION_NONE line.c_str(),line.size(),pre);
// next line, if any
aText=p;
} // loop until all text done
@@ -877,7 +931,7 @@ void TDebugLoggerBase::DebugPuts(uInt32 aDbgMask, cAppCharP aText, stringSize aT
// open new Block with attribute list, varargs passed
-void TDebugLoggerBase::DebugVOpenBlock(cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, va_list aArgs)
+void TDebugLoggerBase::DebugVOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, va_list aArgs)
{
if (!fDbgOptionsP)
return;
@@ -920,7 +974,7 @@ void TDebugLoggerBase::DebugVOpenBlock(cAppCharP aBlockName, cAppCharP aBlockTit
}
StringObjAppendPrintf(bl,"<a name=\"H%ld\">", long(getBlockNo()));
if (withTime) {
- bl+="[" + ts + "] ";
+ bl+=TDbg2Link(TDBG_LOCATION_ARG string("[") + ts + "] ");
}
bl+="'";
bl+=aBlockName;
@@ -1035,7 +1089,7 @@ void TDebugLoggerBase::DebugVOpenBlock(cAppCharP aBlockName, cAppCharP aBlockTit
break;
} // switch preamble
// now output Block line (on current indent level)
- DebugPutLine(bl.c_str(), bl.size());
+ DebugPutLine(TDBG_LOCATION_NONE bl.c_str(), bl.size());
// increase indent level (applies to all Block contents)
fIndent++;
// save Block on stack
@@ -1050,18 +1104,18 @@ void TDebugLoggerBase::DebugVOpenBlock(cAppCharP aBlockName, cAppCharP aBlockTit
// close named Block. If no name given, topmost Block will be closed
-void TDebugLoggerBase::DebugCloseBlock(cAppCharP aBlockName)
+void TDebugLoggerBase::DebugCloseBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName)
{
if (fOutStarted && getMask() && fDbgOptionsP && fBlockHistory) {
if (aBlockName==NULL) {
#if SYDEBUG>1
- internalCloseBlocks(fBlockHistory->fBlockName.c_str(),"Block Nest Warning: Missing Block name at close");
+ internalCloseBlocks(TDBG_LOCATION_ARG fBlockHistory->fBlockName.c_str(),"Block Nest Warning: Missing Block name at close");
#else
- internalCloseBlocks(fBlockHistory->fBlockName.c_str(),NULL);
+ internalCloseBlocks(TDBG_LOCATION_ARG fBlockHistory->fBlockName.c_str(),NULL);
#endif
}
else {
- internalCloseBlocks(aBlockName,NULL);
+ internalCloseBlocks(TDBG_LOCATION_ARG aBlockName,NULL);
}
}
} // TDebugLoggerBase::DebugCloseBlock
@@ -1069,7 +1123,7 @@ void TDebugLoggerBase::DebugCloseBlock(cAppCharP aBlockName)
// internal helper used to close all or some Blocks
-void TDebugLoggerBase::internalCloseBlocks(cAppCharP aBlockName, cAppCharP aCloseComment)
+void TDebugLoggerBase::internalCloseBlocks(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aCloseComment)
{
if (!fDbgOptionsP) return; // security
bool withTime = fDbgOptionsP->fTimestampStructure;
@@ -1077,7 +1131,7 @@ void TDebugLoggerBase::internalCloseBlocks(cAppCharP aBlockName, cAppCharP aClos
#if SYDEBUG>1
if (!fBlockHistory && aBlockName) {
// no blocks open any more and not close-all-remaining call (log close...)
- DebugPrintf(DBG_EXOTIC+DBG_ERROR,"Block Nest Warning: Trying to close block '%s', but no block is open",aBlockName);
+ DebugPrintf(TDBG_LOCATION_ARG DBG_EXOTIC+DBG_ERROR,"Block Nest Warning: Trying to close block '%s', but no block is open",aBlockName);
}
#endif
while (fBlockHistory) {
@@ -1106,7 +1160,7 @@ void TDebugLoggerBase::internalCloseBlocks(cAppCharP aBlockName, cAppCharP aClos
// for XML, the time must be shown before the close tag on a separate line
if (fDbgOptionsP->fOutputFormat == dbgfmt_xml) {
StringObjPrintf(bl,"<endblock time=\"%s\"/>",ts.c_str());
- DebugPutLine(bl.c_str(), bl.size()); // still within block, indented
+ DebugPutLine(TDBG_LOCATION_NONE bl.c_str(), bl.size()); // still within block, indented
}
}
// - now unindent
@@ -1138,7 +1192,7 @@ void TDebugLoggerBase::internalCloseBlocks(cAppCharP aBlockName, cAppCharP aClos
}
StringObjAppendPrintf(bl,"<a name=\"F%ld\">",long(fBlockHistory->fBlockNo));
if (withTime) {
- bl+="[" + ts + "] ";
+ bl+=TDbg2Link(TDBG_LOCATION_ARG string("[") + ts + "] ");
}
bl += "End of '";
bl+=fBlockHistory->fBlockName;
@@ -1170,7 +1224,7 @@ void TDebugLoggerBase::internalCloseBlocks(cAppCharP aBlockName, cAppCharP aClos
break;
} // switch Block close
// - output closing Block line
- DebugPutLine(bl.c_str(), bl.size());
+ DebugPutLine(TDBG_LOCATION_NONE bl.c_str(), bl.size());
// - remove Block level
TBlockLevel *closedLevel = fBlockHistory;
fBlockHistory = closedLevel->fNext;
@@ -1212,10 +1266,10 @@ bool TDebugLoggerBase::DebugStartOutput(void)
// 256 is a safe assumption because the "fold" button <divs> alone are around 250 bytes
fBlockNo = 1 + (fDbgOutP->dbgFileSize()/256);
// now create required prefix
- DebugPutLine(fDbgOptionsP->fCustomPrefix.empty() ? DbgOutDefaultPrefixes[fDbgOptionsP->fOutputFormat] : fDbgOptionsP->fCustomPrefix.c_str());
+ DebugPutLine(TDBG_LOCATION_NONE fDbgOptionsP->fCustomPrefix.empty() ? DbgOutDefaultPrefixes[fDbgOptionsP->fOutputFormat] : fDbgOptionsP->fCustomPrefix.c_str());
// add folding javascript if needed
if (fDbgOptionsP->fOutputFormat==dbgfmt_html && fDbgOptionsP->fFoldingMode!=dbgfold_none) {
- DebugPutLine(FoldingPrefix);
+ DebugPutLine(TDBG_LOCATION_NONE FoldingPrefix);
}
} // debug channel opened successfully
} // use own debug channel
@@ -1229,17 +1283,17 @@ void TDebugLoggerBase::DebugFinalizeOutput(void)
{
if (fOutputLoggerP) {
// just close my own blocks
- internalCloseBlocks(NULL,"closed because sub-log ends here");
+ internalCloseBlocks(TDBG_LOCATION_NONE NULL,"closed because sub-log ends here");
}
if (fOutStarted && fDbgOptionsP && fDbgOutP) {
// close all left-open open Blocks
- internalCloseBlocks(NULL,"closed because log ends here");
+ internalCloseBlocks(TDBG_LOCATION_NONE NULL,"closed because log ends here");
// now finalize output
// - special stuff before
if (fDbgOptionsP->fOutputFormat == dbgfmt_xml)
fIndent=0; // unindent to zero (document is not a real Block)
// - then suffix
- DebugPutLine(fDbgOptionsP->fCustomSuffix.empty() ? DbgOutDefaultSuffixes[fDbgOptionsP->fOutputFormat] : fDbgOptionsP->fCustomSuffix.c_str());
+ DebugPutLine(TDBG_LOCATION_NONE fDbgOptionsP->fCustomSuffix.empty() ? DbgOutDefaultSuffixes[fDbgOptionsP->fOutputFormat] : fDbgOptionsP->fCustomSuffix.c_str());
// now close the debug channel
fDbgOutP->closeDbg();
}
@@ -1249,7 +1303,7 @@ void TDebugLoggerBase::DebugFinalizeOutput(void)
// Output single line to debug channel (includes indenting and other prefixing, but no further formatting)
-void TDebugLoggerBase::DebugPutLine(cAppCharP aText, stringSize aTextSize, bool aPre)
+void TDebugLoggerBase::DebugPutLine(TDBG_LOCATION_PROTO cAppCharP aText, stringSize aTextSize, bool aPre)
{
if (!aText || (!fDbgOutP && !fOutputLoggerP)) return;
if (*aText) {
@@ -1445,31 +1499,31 @@ TDebugLoggerBase &TDebugLogger::setNextMask(uInt32 aDbgMask)
// output text to debug channel, with checking for subthreads
-void TDebugLogger::DebugPuts(uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize, bool aPreFormatted)
+void TDebugLogger::DebugPuts(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize, bool aPreFormatted)
{
TDebugLoggerBase *loggerP = getThreadLogger();
- if (loggerP) loggerP->inherited::DebugPuts(aDbgMask,aText,aTextSize,aPreFormatted);
+ if (loggerP) loggerP->inherited::DebugPuts(TDBG_LOCATION_ARG aDbgMask,aText,aTextSize,aPreFormatted);
} // TDebugLogger::DebugPuts
-void TDebugLogger::DebugVPrintf(uInt32 aDbgMask, cAppCharP aFormat, va_list aArgs)
+void TDebugLogger::DebugVPrintf(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aFormat, va_list aArgs)
{
TDebugLoggerBase *loggerP = getThreadLogger();
- if (loggerP) loggerP->inherited::DebugVPrintf(aDbgMask,aFormat,aArgs);
+ if (loggerP) loggerP->inherited::DebugVPrintf(TDBG_LOCATION_ARG aDbgMask,aFormat,aArgs);
} // TDebugLogger::DebugVPrintf
-void TDebugLogger::DebugVOpenBlock(cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, va_list aArgs)
+void TDebugLogger::DebugVOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, va_list aArgs)
{
TDebugLoggerBase *loggerP = getThreadLogger();
- if (loggerP) loggerP->inherited::DebugVOpenBlock(aBlockName, aBlockTitle, aCollapsed, aBlockFmt, aArgs);
+ if (loggerP) loggerP->inherited::DebugVOpenBlock(TDBG_LOCATION_ARG aBlockName, aBlockTitle, aCollapsed, aBlockFmt, aArgs);
} // TDebugLogger::DebugVOpenBlock
-void TDebugLogger:: DebugCloseBlock(cAppCharP aBlockName)
+void TDebugLogger:: DebugCloseBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName)
{
TDebugLoggerBase *loggerP = getThreadLogger();
- if (loggerP) loggerP->inherited::DebugCloseBlock(aBlockName);
+ if (loggerP) loggerP->inherited::DebugCloseBlock(TDBG_LOCATION_ARG aBlockName);
} // TDebugLogger::DebugCloseBlock
#endif
diff --git a/src/sysync/debuglogger.h b/src/sysync/debuglogger.h
index 64d2531..84362e1 100755
--- a/src/sysync/debuglogger.h
+++ b/src/sysync/debuglogger.h
@@ -57,6 +57,42 @@ typedef enum {
numDbgSubthreadModes
} TDbgSubthreadModes;
+/// Container for information about the location where a debug call was made.
+/// Strings are owned by caller.
+struct TDbgLocation {
+ /// function name, may be NULL, derived from __FUNC__ if available
+ const char *fFunction;
+ /// file name, may be NULL, from __FILE__
+ const char *fFile;
+ /// line number, 0 if unknown
+ const int fLine;
+
+ TDbgLocation(const char *aFunction = NULL,
+ const char *aFile = NULL,
+ const int aLine = 0) :
+ fFunction(aFunction),
+ fFile(aFile),
+ fLine(aLine)
+ {}
+};
+
+#ifdef SYDEBUG_LOCATION
+# define TDBG_LOCATION_PROTO const TDbgLocation &aTDbgLoc,
+# define TDBG_LOCATION_ARG aTDbgLoc,
+# define TDBG_LOCATION_HERE TDbgLocation(__func__, __FILE__, __LINE__),
+# define TDBG_LOCATION_NONE TDbgLocation(),
+# define TDBG_LOCATION_ARGS(_func, _file, _line) TDbgLocation(_func, _file, _line),
+# define TDBG_VARARGS(m...) (TDbgLocation(__PRETTY_FUNCTION__, __FILE__, __LINE__), ## m)
+# define TDBG_LOCATION_ARG_NUM 1
+#else
+# define TDBG_LOCATION_PROTO
+# define TDBG_LOCATION_ARG
+# define TDBG_LOCATION_HERE
+# define TDBG_LOCATION_NONE
+# define TDBG_LOCATION_ARGS(_func, _file, _line)
+# define TDBG_VARARGS
+# define TDBG_LOCATION_ARG_NUM 0
+#endif
#ifndef HARDCODED_CONFIG
extern cAppCharP const DbgOutFormatNames[numDbgOutFormats];
@@ -237,18 +273,18 @@ public:
/// @param aDbgMask debug mask, bits set here must be set in the debuglogger's own mask in order to display the debug text
/// @param aText[in] text to be written out
/// @param aTextSize[in] if>0, this is the maximum number of chars to output from aText
- virtual void DebugPuts(uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize=0, bool aPreFormatted=false);
+ virtual void DebugPuts(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize=0, bool aPreFormatted=false);
/// @brief Write formatted text to debug output channel.
/// @param aDbgMask debug mask, bits set here must be set in the debuglogger's own mask in order to display the debug text
/// @param aFormat[in] format text in vprintf style to be written out
/// @param aArgs[in] varargs in vprintf style
- virtual void DebugVPrintf(uInt32 aDbgMask, cAppCharP aFormat, va_list aArgs);
+ virtual void DebugVPrintf(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aFormat, va_list aArgs);
/// @brief Write formatted text to debug output channel.
/// @param aDbgMask debug mask, bits set here must be set in the debuglogger's own mask in order to display the debug text
/// @param aFormat[in] format text in printf style to be written out
- void DebugPrintf(uInt32 aDbgMask, cAppCharP aFormat, ...)
+ void DebugPrintf(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aFormat, ...)
#ifdef __GNUC__
- __attribute__((format(printf, 3, 4)))
+ __attribute__((format(printf, TDBG_LOCATION_ARG_NUM + 3, TDBG_LOCATION_ARG_NUM + 4)))
#endif
;
/// @brief set debug mask to be used for next DebugPrintfLastMask() call
@@ -256,9 +292,9 @@ public:
virtual TDebugLoggerBase &setNextMask(uInt32 aDbgMask);
/// @brief like DebugPrintf(), but using mask previously set by setNextMask()
/// @param aFormat[in] format text in printf style to be written out
- void DebugPrintfLastMask(cAppCharP aFormat, ...)
+ void DebugPrintfLastMask(TDBG_LOCATION_PROTO cAppCharP aFormat, ...)
#ifdef __GNUC__
- __attribute__((format(printf, 2, 3)))
+ __attribute__((format(printf, TDBG_LOCATION_ARG_NUM + 2, TDBG_LOCATION_ARG_NUM + 3)))
#endif
;
// - Blocks
@@ -269,33 +305,33 @@ public:
/// @param aBlockFmt[in] Format string for additional Block info. Should contain one or multiple tag=value pairs, separated by the pipe char |.
/// This will be used to generate XML attributes or other identifiers.
/// @param aArgs[in] varargs in vprintf style for aBlockFmt
- virtual void DebugVOpenBlock(cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, va_list aArgs);
+ virtual void DebugVOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, va_list aArgs);
/// @brief Open structure Block, printf style variant
- void DebugOpenBlock(cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, ...)
+ void DebugOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, ...)
#ifdef __GNUC__
- __attribute__((format(printf, 5, 6)))
+ __attribute__((format(printf, TDBG_LOCATION_ARG_NUM + 5, TDBG_LOCATION_ARG_NUM + 6)))
#endif
;
- void DebugOpenBlockExpanded(cAppCharP aBlockName, cAppCharP aBlockTitle, cAppCharP aBlockFmt, ...)
+ void DebugOpenBlockExpanded(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, cAppCharP aBlockFmt, ...)
#ifdef __GNUC__
- __attribute__((format(printf, 4, 5)))
+ __attribute__((format(printf, TDBG_LOCATION_ARG_NUM + 4, TDBG_LOCATION_ARG_NUM + 5)))
#endif
;
- void DebugOpenBlockCollapsed(cAppCharP aBlockName, cAppCharP aBlockTitle, cAppCharP aBlockFmt, ...)
+ void DebugOpenBlockCollapsed(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, cAppCharP aBlockFmt, ...)
#ifdef __GNUC__
- __attribute__((format(printf, 4, 5)))
+ __attribute__((format(printf, TDBG_LOCATION_ARG_NUM + 4, TDBG_LOCATION_ARG_NUM + 5)))
#endif
;
/// @brief Open structure Block, without any attributes
- virtual void DebugOpenBlock(cAppCharP aBlockName, cAppCharP aBlockTitle=NULL, bool aCollapsed=false);
+ virtual void DebugOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle=NULL, bool aCollapsed=false);
/// @brief Close structure Block. Name is used to close possibly unclosed contained Blocks automatically.
- virtual void DebugCloseBlock(cAppCharP aBlockName);
+ virtual void DebugCloseBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName);
protected:
// helper methods
/// @brief start debugging output if needed and sets fOutStarted
bool DebugStartOutput(void);
/// @brief Output single line to debug channel (includes indenting, but no other formatting)
- void DebugPutLine(cAppCharP aText, stringSize aTextSize=0, bool aPre=false);
+ void DebugPutLine(TDBG_LOCATION_PROTO cAppCharP aText, stringSize aTextSize=0, bool aPre=false);
/// @brief finalize debugging output
void DebugFinalizeOutput(void);
/// @brief get block number
@@ -305,7 +341,7 @@ protected:
/// @brief internal helper for closing debug Blocks
/// @param aBlockName[in] Name of Block to close. All Blocks including the first with given name will be closed. If NULL, all Blocks will be closed.
/// @param aCloseComment[in] Comment about closing Block. If NULL, no comment will be shown (unless implicit closes occur, which auto-creates a comment)
- void internalCloseBlocks(cAppCharP aBlockName, cAppCharP aCloseComment);
+ void internalCloseBlocks(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aCloseComment);
// Variables
TDbgOut *fDbgOutP; // the debug output
string fDbgPath; // the output path+filename (w/o extension)
@@ -342,10 +378,10 @@ public:
virtual ~TDebugLogger();
// methods
#ifdef MULTI_THREAD_SUPPORT
- virtual void DebugPuts(uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize=0, bool aPreFormatted=false);
- virtual void DebugVPrintf(uInt32 aDbgMask, cAppCharP aFormat, va_list aArgs);
- virtual void DebugVOpenBlock(cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, va_list aArgs);
- virtual void DebugCloseBlock(cAppCharP aBlockName);
+ virtual void DebugPuts(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aText, stringSize aTextSize=0, bool aPreFormatted=false);
+ virtual void DebugVPrintf(TDBG_LOCATION_PROTO uInt32 aDbgMask, cAppCharP aFormat, va_list aArgs);
+ virtual void DebugVOpenBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName, cAppCharP aBlockTitle, bool aCollapsed, cAppCharP aBlockFmt, va_list aArgs);
+ virtual void DebugCloseBlock(TDBG_LOCATION_PROTO cAppCharP aBlockName);
virtual TDebugLoggerBase &setNextMask(uInt32 aDbgMask);
#endif
// - thread debug output serializing
diff --git a/src/sysync/engineinterface.cpp b/src/sysync/engineinterface.cpp
index 40357cd..8d5f9b1 100644
--- a/src/sysync/engineinterface.cpp
+++ b/src/sysync/engineinterface.cpp
@@ -1848,7 +1848,7 @@ TSyError TEngineInterface::debugPuts(cAppCharP aFile, int aLine, cAppCharP aFunc
cAppCharP aText)
{
#if defined(SYDEBUG)
- getSyncAppBase()->getDbgLogger()->DebugPuts(/* aFile, aLine, aFunction, aPrefix */
+ getSyncAppBase()->getDbgLogger()->DebugPuts(TDBG_LOCATION_ARGS(aFunction, aFile, aLine /*, aPrefix */)
aDbgLevel, aText);
return 0;
#else
diff --git a/src/sysync/syncappbase.cpp b/src/sysync/syncappbase.cpp
index c4093ef..068c65f 100755
--- a/src/sysync/syncappbase.cpp
+++ b/src/sysync/syncappbase.cpp
@@ -220,7 +220,7 @@ extern "C" void AppBaseLogDebugBlock(void *aCallbackRef, const char *aTag, const
if (aCallbackRef) {
bool collapsed=false;
if (aTag && aTag[0]=='-') { aTag++; collapsed=true; }
- static_cast<TSyncAppBase *>(aCallbackRef)->getDbgLogger()->DebugOpenBlock(aTag,aDesc,collapsed,"%s",aAttrText);
+ static_cast<TSyncAppBase *>(aCallbackRef)->getDbgLogger()->DebugOpenBlock(TDBG_LOCATION_NONE aTag,aDesc,collapsed,"%s",aAttrText);
}
} // AppBaseLogDebugBlock
@@ -229,7 +229,7 @@ extern "C" void AppBaseLogDebugEndBlock(void *aCallbackRef, const char *aTag)
{
if (aCallbackRef) {
if (aTag && aTag[0]=='-') aTag++;
- static_cast<TSyncAppBase *>(aCallbackRef)->getDbgLogger()->DebugCloseBlock(aTag);
+ static_cast<TSyncAppBase *>(aCallbackRef)->getDbgLogger()->DebugCloseBlock(TDBG_LOCATION_NONE aTag);
}
} // AppBaseLogDebugEndBlock
diff --git a/src/sysync/syncclientbase.cpp b/src/sysync/syncclientbase.cpp
index 6b4f50c..bbc0c71 100644
--- a/src/sysync/syncclientbase.cpp
+++ b/src/sysync/syncclientbase.cpp
@@ -197,7 +197,7 @@ TSyError TClientEngineInterface::debugPuts(cAppCharP aFile, int aLine, cAppCharP
cAppCharP aText)
{
#if defined(SYDEBUG)
- static_cast<TSyncClientBase *>(getSyncAppBase())->getDbgLogger()->DebugPuts(/* aFile, aLine, aFunction, aPrefix */
+ static_cast<TSyncClientBase *>(getSyncAppBase())->getDbgLogger()->DebugPuts(TDBG_LOCATION_ARGS(aFunction, aFile, aLine /* aPrefix */)
aDbgLevel, aText);
return 0;
#else
diff --git a/src/sysync/sysync_debug.h b/src/sysync/sysync_debug.h
index 007d625..6791809 100755
--- a/src/sysync/sysync_debug.h
+++ b/src/sysync/sysync_debug.h
@@ -123,52 +123,52 @@ TDebugLogger *getDbgLogger(void);
#ifdef SYDEBUG
// "Public" debug info
// Debug structure
- #define PDEBUGBLOCKFMT(m) getDbgLogger()->DebugOpenBlockExpanded m
- #define PDEBUGBLOCKFMTCOLL(m) getDbgLogger()->DebugOpenBlockCollapsed m
- #define PDEBUGBLOCKDESC(n,d) getDbgLogger()->DebugOpenBlock(n,d)
- #define PDEBUGBLOCKDESCCOLL(n,d) getDbgLogger()->DebugOpenBlock(n,d,true)
- #define PDEBUGBLOCK(n) getDbgLogger()->DebugOpenBlock(n)
- #define PDEBUGBLOCKCOLL(n) getDbgLogger()->DebugOpenBlock(n,NULL,true)
- #define PDEBUGENDBLOCK(n) getDbgLogger()->DebugCloseBlock(n)
+ #define PDEBUGBLOCKFMT(m) getDbgLogger()->DebugOpenBlockExpanded TDBG_VARARGS m
+ #define PDEBUGBLOCKFMTCOLL(m) getDbgLogger()->DebugOpenBlockCollapsed TDBG_VARARGS m
+ #define PDEBUGBLOCKDESC(n,d) getDbgLogger()->DebugOpenBlock(TDBG_LOCATION_HERE n,d)
+ #define PDEBUGBLOCKDESCCOLL(n,d) getDbgLogger()->DebugOpenBlock(TDBG_LOCATION_HERE n,d,true)
+ #define PDEBUGBLOCK(n) getDbgLogger()->DebugOpenBlock(TDBG_LOCATION_HERE n)
+ #define PDEBUGBLOCKCOLL(n) getDbgLogger()->DebugOpenBlock(TDBG_LOCATION_HERE n,NULL,true)
+ #define PDEBUGENDBLOCK(n) getDbgLogger()->DebugCloseBlock(TDBG_LOCATION_HERE n)
// current-class context debug output
- #define PDEBUGPUTSX(lvl,m) { if (((lvl) & getDbgMask()) == (lvl)) getDbgLogger()->DebugPuts(lvl,m); }
- #define PDEBUGPUTSXX(lvl,m,s,p) { if (((lvl) & getDbgMask()) == (lvl)) getDbgLogger()->DebugPuts(lvl,m,s,p); }
+ #define PDEBUGPUTSX(lvl,m) { if (((lvl) & getDbgMask()) == (lvl)) getDbgLogger()->DebugPuts(TDBG_LOCATION_HERE lvl,m); }
+ #define PDEBUGPUTSXX(lvl,m,s,p) { if (((lvl) & getDbgMask()) == (lvl)) getDbgLogger()->DebugPuts(TDBG_LOCATION_HERE lvl,m,s,p); }
#define PDEBUGPUTS(m) PDEBUGPUTSX(DBG_REST,m)
- #define PDEBUGVPRINTFX(lvl,f,a) { if (((lvl) & getDbgMask()) == (lvl)) getDbgLogger()->DebugVPrintf(lvl,f,a); }
- #define PDEBUGPRINTFX(lvl,m) { if (((lvl) & getDbgMask()) == (lvl)) getDbgLogger()->setNextMask(lvl).DebugPrintfLastMask m; }
+ #define PDEBUGVPRINTFX(lvl,f,a) { if (((lvl) & getDbgMask()) == (lvl)) getDbgLogger()->DebugVPrintf(TDBG_LOCATION_HERE lvl,f,a); }
+ #define PDEBUGPRINTFX(lvl,m) { if (((lvl) & getDbgMask()) == (lvl)) getDbgLogger()->setNextMask(lvl).DebugPrintfLastMask TDBG_VARARGS m; }
#define PDEBUGPRINTF(m) PDEBUGPRINTFX(DBG_REST,m)
- #define PPOINTERTEST(p,m) if (!p) getDbgLogger()->setNextMask(DBG_ERROR).DebugPrintfLastMask m
+ #define PPOINTERTEST(p,m) if (!p) getDbgLogger()->setNextMask(DBG_ERROR).DebugPrintfLastMask TDBG_VARARGS m
#define PDEBUGTEST(lvl) (((lvl) & getDbgMask()) == (lvl))
#define PDEBUGMASK getDbgMask()
// direct output to a logger
#define PLOGDEBUGTEST(lo,lvl) ((lo) && (((lvl) & (lo)->getMask()) == (lvl)))
- #define PLOGDEBUGBLOCKFMT(lo,m) { if (lo) (lo)->DebugOpenBlockExpanded m; }
- #define PLOGDEBUGBLOCKFMTCOLL(lo,m) { if (lo) (lo)->DebugOpenBlockCollapsed m; }
- #define PLOGDEBUGBLOCKDESC(lo,n,d) { if (lo) (lo)->DebugOpenBlock(n,d); }
- #define PLOGDEBUGBLOCKDESCCOLL(lo,n,d) { if (lo) (lo)->DebugOpenBlock(n,d,true); }
- #define PLOGDEBUGBLOCK(lo,n) { if (lo) (lo)->DebugOpenBlock(n); }
- #define PLOGDEBUGBLOCKCOLL(lo,n) { if (lo) (lo)->DebugOpenBlock(n,NULL,true); }
- #define PLOGDEBUGENDBLOCK(lo,n) { if (lo) (lo)->DebugCloseBlock(n); }
- #define PLOGDEBUGPUTSX(lo,lvl,m) { if ((lo) && ((lvl) & (lo)->getMask()) == (lvl)) (lo)->DebugPuts(lvl,m); }
- #define PLOGDEBUGPUTSXX(lo,lvl,m,s,p) { if ((lo) && ((lvl) & (lo)->getMask()) == (lvl)) (lo)->DebugPuts(lvl,m,s,p); }
- #define PLOGDEBUGVPRINTFX(lo,lvl,f,a) { if ((lo) && ((lvl) & (lo)->getMask()) == (lvl)) (lo)->DebugVPrintf(lvl,f,a); }
- #define PLOGDEBUGPRINTFX(lo,lvl,m) { if ((lo) && ((lvl) & (lo)->getMask()) == (lvl)) (lo)->setNextMask(lvl).DebugPrintfLastMask m; }
+ #define PLOGDEBUGBLOCKFMT(lo,m) { if (lo) (lo)->DebugOpenBlockExpanded TDBG_VARARGS m; }
+ #define PLOGDEBUGBLOCKFMTCOLL(lo,m) { if (lo) (lo)->DebugOpenBlockCollapsed TDBG_VARARGS m; }
+ #define PLOGDEBUGBLOCKDESC(lo,n,d) { if (lo) (lo)->DebugOpenBlock(TDBG_LOCATION_HERE n,d); }
+ #define PLOGDEBUGBLOCKDESCCOLL(lo,n,d) { if (lo) (lo)->DebugOpenBlock(TDBG_LOCATION_HERE n,d,true); }
+ #define PLOGDEBUGBLOCK(lo,n) { if (lo) (lo)->DebugOpenBlock(TDBG_LOCATION_HERE n); }
+ #define PLOGDEBUGBLOCKCOLL(lo,n) { if (lo) (lo)->DebugOpenBlock(TDBG_LOCATION_HERE n,NULL,true); }
+ #define PLOGDEBUGENDBLOCK(lo,n) { if (lo) (lo)->DebugCloseBlock(TDBG_LOCATION_HERE n); }
+ #define PLOGDEBUGPUTSX(lo,lvl,m) { if ((lo) && ((lvl) & (lo)->getMask()) == (lvl)) (lo)->DebugPuts(TDBG_LOCATION_HERE lvl,m); }
+ #define PLOGDEBUGPUTSXX(lo,lvl,m,s,p) { if ((lo) && ((lvl) & (lo)->getMask()) == (lvl)) (lo)->DebugPuts(TDBG_LOCATION_HERE lvl,m,s,p); }
+ #define PLOGDEBUGVPRINTFX(lo,lvl,f,a) { if ((lo) && ((lvl) & (lo)->getMask()) == (lvl)) (lo)->DebugVPrintf(TDBG_LOCATION_HERE lvl,f,a); }
+ #define PLOGDEBUGPRINTFX(lo,lvl,m) { if ((lo) && ((lvl) & (lo)->getMask()) == (lvl)) (lo)->setNextMask(lvl).DebugPrintfLastMask TDBG_VARARGS m; }
// non-class context or C-level debug output
#ifdef DIRECT_APPBASE_GLOBALACCESS
#ifdef __cplusplus
- #define PNCDEBUGPUTSX(lvl,m) { if (((lvl) & sysync::getDbgMask()) == (lvl)) sysync::DebugPuts(m); }
- #define PNCDEBUGPRINTFX(lvl,m) { if (((lvl) & sysync::getDbgMask()) == (lvl)) sysync::DebugPrintf m; }
- #define PNCDEBUGVPRINTFX(lvl,f,a) { if (((lvl) & sysync::getDbgMask()) == (lvl)) sysync::DebugVPrintf(lvl,f,a); }
+ #define PNCDEBUGPUTSX(lvl,m) { if (((lvl) & sysync::getDbgMask()) == (lvl)) sysync::DebugPuts(TDBG_LOCATION_HERE m); }
+ #define PNCDEBUGPRINTFX(lvl,m) { if (((lvl) & sysync::getDbgMask()) == (lvl)) sysync::DebugPrintf TDBG_VARARGS m; }
+ #define PNCDEBUGVPRINTFX(lvl,f,a) { if (((lvl) & sysync::getDbgMask()) == (lvl)) sysync::DebugVPrintf(TDBG_LOCATION_HERE lvl,f,a); }
#else
- #define PNCDEBUGPUTSX(lvl,m) { if (((lvl) & getDbgMask()) == (lvl)) DebugPuts(m); }
- #define PNCDEBUGPRINTFX(lvl,m) { if (((lvl) & getDbgMask()) == (lvl)) DebugPrintf m; }
- #define PNCDEBUGVPRINTFX(lvl,f,a) { if (((lvl) & getDbgMask()) == (lvl)) DebugVPrintf(lvl,f,a); }
+ #define PNCDEBUGPUTSX(lvl,m) { if (((lvl) & getDbgMask()) == (lvl)) DebugPuts(TDBG_LOCATION_HERE m); }
+ #define PNCDEBUGPRINTFX(lvl,m) { if (((lvl) & getDbgMask()) == (lvl)) DebugPrintf TDBG_VARARGS m; }
+ #define PNCDEBUGVPRINTFX(lvl,f,a) { if (((lvl) & getDbgMask()) == (lvl)) DebugVPrintf(TDBG_LOCATION_HERE lvl,f,a); }
#endif
#endif
// specified object-context debug output
- #define POBJDEBUGPRINTFX(obj,lvl,m) { if ((obj) && (((lvl) & (obj)->getDbgMask()) == (lvl))) (obj)->getDbgLogger()->setNextMask(lvl).DebugPrintfLastMask m; }
- #define POBJDEBUGPUTSX(obj,lvl,m) { if ((obj) && (((lvl) & (obj)->getDbgMask()) == (lvl))) (obj)->getDbgLogger()->DebugPuts(lvl,m); }
- #define POBJDEBUGPUTSXX(obj,lvl,m,s,p) { if ((obj) && (((lvl) & (obj)->getDbgMask()) == (lvl))) (obj)->getDbgLogger()->DebugPuts(lvl,m,s,p); }
+ #define POBJDEBUGPRINTFX(obj,lvl,m) { if ((obj) && (((lvl) & (obj)->getDbgMask()) == (lvl))) (obj)->getDbgLogger()->setNextMask(lvl).DebugPrintfLastMask TDBG_VARARGS m; }
+ #define POBJDEBUGPUTSX(obj,lvl,m) { if ((obj) && (((lvl) & (obj)->getDbgMask()) == (lvl))) (obj)->getDbgLogger()->DebugPuts(TDBG_LOCATION_HERE lvl,m); }
+ #define POBJDEBUGPUTSXX(obj,lvl,m,s,p) { if ((obj) && (((lvl) & (obj)->getDbgMask()) == (lvl))) (obj)->getDbgLogger()->DebugPuts(TDBG_LOCATION_HERE lvl,m,s,p); }
#define POBJDEBUGPRINTF(obj,m) POBJDEBUGPRINTFX(obj,DBG_REST,m)
#define POBJDEBUGTEST(obj,lvl) ((obj) && (((lvl) & (obj)->getDbgMask()) == (lvl)))
// get current logger