Home | History | Annotate | Download | only in wtf
      1 /*
      2  * Copyright (C) 2003, 2006, 2007 Apple Inc.  All rights reserved.
      3  * Copyright (C) 2007-2009 Torch Mobile, Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "config.h"
     28 #include "Assertions.h"
     29 
     30 #include <stdio.h>
     31 #include <stdarg.h>
     32 #include <string.h>
     33 
     34 #if PLATFORM(MAC)
     35 #include <CoreFoundation/CFString.h>
     36 #endif
     37 
     38 #if COMPILER(MSVC) && !OS(WINCE)
     39 #ifndef WINVER
     40 #define WINVER 0x0500
     41 #endif
     42 #ifndef _WIN32_WINNT
     43 #define _WIN32_WINNT 0x0500
     44 #endif
     45 #include <windows.h>
     46 #include <crtdbg.h>
     47 #endif
     48 
     49 #if OS(WINCE)
     50 #include <winbase.h>
     51 #endif
     52 
     53 extern "C" {
     54 
     55 WTF_ATTRIBUTE_PRINTF(1, 0)
     56 static void vprintf_stderr_common(const char* format, va_list args)
     57 {
     58 #if PLATFORM(MAC)
     59     if (strstr(format, "%@")) {
     60         CFStringRef cfFormat = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8);
     61         CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, cfFormat, args);
     62 
     63         int length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
     64         char* buffer = (char*)malloc(length + 1);
     65 
     66         CFStringGetCString(str, buffer, length, kCFStringEncodingUTF8);
     67 
     68         fputs(buffer, stderr);
     69 
     70         free(buffer);
     71         CFRelease(str);
     72         CFRelease(cfFormat);
     73     } else
     74 #elif COMPILER(MSVC) && !defined(WINCEBASIC)
     75     if (IsDebuggerPresent()) {
     76         size_t size = 1024;
     77 
     78         do {
     79             char* buffer = (char*)malloc(size);
     80 
     81             if (buffer == NULL)
     82                 break;
     83 
     84             if (_vsnprintf(buffer, size, format, args) != -1) {
     85 #if OS(WINCE)
     86                 // WinCE only supports wide chars
     87                 wchar_t* wideBuffer = (wchar_t*)malloc(size * sizeof(wchar_t));
     88                 if (wideBuffer == NULL)
     89                     break;
     90                 for (unsigned int i = 0; i < size; ++i) {
     91                     if (!(wideBuffer[i] = buffer[i]))
     92                         break;
     93                 }
     94                 OutputDebugStringW(wideBuffer);
     95                 free(wideBuffer);
     96 #else
     97                 OutputDebugStringA(buffer);
     98 #endif
     99                 free(buffer);
    100                 break;
    101             }
    102 
    103             free(buffer);
    104             size *= 2;
    105         } while (size > 1024);
    106     }
    107 #endif
    108 #if OS(SYMBIAN)
    109     vfprintf(stdout, format, args);
    110 #else
    111     vfprintf(stderr, format, args);
    112 #endif
    113 }
    114 
    115 WTF_ATTRIBUTE_PRINTF(1, 2)
    116 static void printf_stderr_common(const char* format, ...)
    117 {
    118     va_list args;
    119     va_start(args, format);
    120     vprintf_stderr_common(format, args);
    121     va_end(args);
    122 }
    123 
    124 static void printCallSite(const char* file, int line, const char* function)
    125 {
    126 #if OS(WIN) && !OS(WINCE) && defined _DEBUG
    127     _CrtDbgReport(_CRT_WARN, file, line, NULL, "%s\n", function);
    128 #else
    129     printf_stderr_common("(%s:%d %s)\n", file, line, function);
    130 #endif
    131 }
    132 
    133 void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion)
    134 {
    135     if (assertion)
    136         printf_stderr_common("ASSERTION FAILED: %s\n", assertion);
    137     else
    138         printf_stderr_common("SHOULD NEVER BE REACHED\n");
    139     printCallSite(file, line, function);
    140 }
    141 
    142 void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...)
    143 {
    144     printf_stderr_common("ASSERTION FAILED: ");
    145     va_list args;
    146     va_start(args, format);
    147     vprintf_stderr_common(format, args);
    148     va_end(args);
    149     printf_stderr_common("\n%s\n", assertion);
    150     printCallSite(file, line, function);
    151 }
    152 
    153 void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion)
    154 {
    155     printf_stderr_common("ARGUMENT BAD: %s, %s\n", argName, assertion);
    156     printCallSite(file, line, function);
    157 }
    158 
    159 void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...)
    160 {
    161     printf_stderr_common("FATAL ERROR: ");
    162     va_list args;
    163     va_start(args, format);
    164     vprintf_stderr_common(format, args);
    165     va_end(args);
    166     printf_stderr_common("\n");
    167     printCallSite(file, line, function);
    168 }
    169 
    170 void WTFReportError(const char* file, int line, const char* function, const char* format, ...)
    171 {
    172     printf_stderr_common("ERROR: ");
    173     va_list args;
    174     va_start(args, format);
    175     vprintf_stderr_common(format, args);
    176     va_end(args);
    177     printf_stderr_common("\n");
    178     printCallSite(file, line, function);
    179 }
    180 
    181 void WTFLog(WTFLogChannel* channel, const char* format, ...)
    182 {
    183     if (channel->state != WTFLogChannelOn)
    184         return;
    185 
    186     va_list args;
    187     va_start(args, format);
    188     vprintf_stderr_common(format, args);
    189     va_end(args);
    190     if (format[strlen(format) - 1] != '\n')
    191         printf_stderr_common("\n");
    192 }
    193 
    194 void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel* channel, const char* format, ...)
    195 {
    196     if (channel->state != WTFLogChannelOn)
    197         return;
    198 
    199     va_list args;
    200     va_start(args, format);
    201     vprintf_stderr_common(format, args);
    202     va_end(args);
    203     if (format[strlen(format) - 1] != '\n')
    204         printf_stderr_common("\n");
    205     printCallSite(file, line, function);
    206 }
    207 
    208 } // extern "C"
    209