1 /* 2 Copyright (c) 2005-2020 Intel Corporation 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // Just the tracing portion of the harness. 18 // 19 // This header defines TRACE and TRACENL macros, which use REPORT like syntax and 20 // are useful for duplicating trace output to the standard debug output on Windows. 21 // It is possible to add the ability of automatic extending messages with additional 22 // info (file, line, function, time, thread ID, ...). 23 // 24 // Macros output nothing when test app runs in non-verbose mode (default). 25 // 26 27 #ifndef tbb_tests_harness_report_H 28 #define tbb_tests_harness_report_H 29 30 #if defined(MAX_TRACE_SIZE) && MAX_TRACE_SIZE < 1024 31 #undef MAX_TRACE_SIZE 32 #endif 33 #ifndef MAX_TRACE_SIZE 34 #define MAX_TRACE_SIZE 1024 35 #endif 36 37 #if __SUNPRO_CC 38 #include <stdio.h> 39 #else 40 #include <cstdio> 41 #endif 42 43 #include <cstdarg> 44 45 // Need to include "tbb/tbb_config.h" to obtain the definition of __TBB_DEFINE_MIC. 46 #include "tbb/tbb_config.h" 47 48 #if __TBB_DEFINE_MIC 49 #include "harness_mic.h" 50 #endif 51 52 #ifdef HARNESS_INCOMPLETE_SOURCES 53 #error Source files are not complete. Check the build environment 54 #endif 55 56 #if _MSC_VER 57 #define snprintf _snprintf 58 #if _MSC_VER<=1400 59 #define vsnprintf _vsnprintf 60 #endif 61 #endif 62 63 namespace Harness { 64 namespace internal { 65 66 #ifndef TbbHarnessReporter 67 struct TbbHarnessReporter { ReportTbbHarnessReporter68 void Report ( const char* msg ) { 69 printf( "%s", msg ); 70 fflush(stdout); 71 #ifdef _WINDOWS_ 72 OutputDebugStringA(msg); 73 #endif 74 } 75 }; // struct TbbHarnessReporter 76 #endif /* !TbbHarnessReporter */ 77 78 class Tracer { 79 int m_flags; 80 const char *m_file; 81 const char *m_func; 82 size_t m_line; 83 84 TbbHarnessReporter m_reporter; 85 86 public: 87 enum { 88 prefix = 1, 89 need_lf = 2 90 }; 91 Tracer()92 Tracer(): m_flags(0), m_file(NULL), m_func(NULL), m_line(0) {} 93 set_trace_info(int flags,const char * file,size_t line,const char * func)94 Tracer* set_trace_info ( int flags, const char *file, size_t line, const char *func ) { 95 m_flags = flags; 96 m_line = line; 97 m_file = file; 98 m_func = func; 99 return this; 100 } 101 trace(const char * fmt,...)102 void trace ( const char* fmt, ... ) { 103 char msg[MAX_TRACE_SIZE]; 104 char msg_fmt_buf[MAX_TRACE_SIZE]; 105 const char *msg_fmt = fmt; 106 if ( m_flags & prefix ) { 107 snprintf (msg_fmt_buf, MAX_TRACE_SIZE, "[%s] %s", m_func, fmt); 108 msg_fmt = msg_fmt_buf; 109 } 110 std::va_list argptr; 111 va_start (argptr, fmt); 112 int len = vsnprintf (msg, MAX_TRACE_SIZE, msg_fmt, argptr); 113 va_end (argptr); 114 if ( m_flags & need_lf && 115 len < MAX_TRACE_SIZE - 1 && msg_fmt[len-1] != '\n' ) 116 { 117 msg[len] = '\n'; 118 msg[len + 1] = 0; 119 } 120 m_reporter.Report(msg); 121 } 122 }; // class Tracer 123 124 static Tracer tracer; 125 126 template<int> not_the_first_call()127 bool not_the_first_call () { 128 static bool first_call = false; 129 bool res = first_call; 130 first_call = true; 131 return res; 132 } 133 134 } // namespace internal 135 } // namespace Harness 136 137 #if defined(_MSC_VER) && _MSC_VER >= 1300 || defined(__GNUC__) || defined(__GNUG__) 138 #define HARNESS_TRACE_ORIG_INFO __FILE__, __LINE__, __FUNCTION__ 139 #else 140 #define HARNESS_TRACE_ORIG_INFO __FILE__, __LINE__, "" 141 #define __FUNCTION__ "" 142 #endif 143 144 145 //! printf style tracing macro 146 /** This variant of TRACE adds trailing line-feed (new line) character, if it is absent. **/ 147 #define TRACE Harness::internal::tracer.set_trace_info(Harness::internal::Tracer::need_lf, HARNESS_TRACE_ORIG_INFO)->trace 148 149 //! printf style tracing macro without automatic new line character adding 150 #define TRACENL Harness::internal::tracer.set_trace_info(0, HARNESS_TRACE_ORIG_INFO)->trace 151 152 //! printf style tracing macro with additional information prefix (e.g. current function name) 153 #define TRACEP Harness::internal::tracer.set_trace_info(Harness::internal::Tracer::prefix | \ 154 Harness::internal::Tracer::need_lf, HARNESS_TRACE_ORIG_INFO)->trace 155 156 //! printf style remark macro 157 /** Produces output only when the test is run with the -v (verbose) option. **/ 158 #define REMARK !Verbose ? (void)0 : TRACENL 159 160 //! printf style remark macro 161 /** Produces output only when invoked first time. 162 Only one instance of this macro is allowed per source code line. **/ 163 #define REMARK_ONCE (!Verbose || Harness::internal::not_the_first_call<__LINE__>()) ? (void)0 : TRACE 164 165 //! printf style reporting macro 166 /** On heterogeneous platforms redirects its output to the host side. **/ 167 #define REPORT TRACENL 168 169 //! printf style reporting macro 170 /** Produces output only when invoked first time. 171 Only one instance of this macro is allowed per source code line. **/ 172 #define REPORT_ONCE (Harness::internal::not_the_first_call<__LINE__>()) ? (void)0 : TRACENL 173 174 #endif /* tbb_tests_harness_report_H */ 175