diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2010-05-11 14:12:42 +0200 |
---|---|---|
committer | Lukas Zeller <luz@synthesis.ch> | 2010-05-13 14:08:48 +0200 |
commit | 7cb91dc4d56a7f09bb47109bd5e048a154ba1517 (patch) | |
tree | ff8e947d2763fb38612614012149c8b275db547a | |
parent | 8270832de3f15a3ab6abaaf9c3dc5c1d4f26b93e (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.cpp | 4 | ||||
-rw-r--r-- | src/Doxyfile | 40 | ||||
-rw-r--r-- | src/Makefile.am.in | 23 | ||||
-rwxr-xr-x | src/sysync/debuglogger.cpp | 156 | ||||
-rwxr-xr-x | src/sysync/debuglogger.h | 78 | ||||
-rw-r--r-- | src/sysync/engineinterface.cpp | 2 | ||||
-rwxr-xr-x | src/sysync/syncappbase.cpp | 4 | ||||
-rw-r--r-- | src/sysync/syncclientbase.cpp | 2 | ||||
-rwxr-xr-x | src/sysync/sysync_debug.h | 64 |
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> "; + prefix+="]</i> "; + + 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 |