Home | History | Annotate | Download | only in qphelper
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program Helper Library
      3  * -------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Debug output utilities.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "qpDebugOut.h"
     25 
     26 #include "qpCrashHandler.h" /*!< for QP_USE_SIGNAL_HANDLER */
     27 
     28 #include <stdio.h>
     29 #include <stdlib.h>
     30 
     31 typedef enum MessageType_e
     32 {
     33 	MESSAGETYPE_INFO	= 0,
     34 	MESSAGETYPE_ERROR,
     35 
     36 	MESSAGETYPE_LAST
     37 } MessageType;
     38 
     39 static void		printRaw		(MessageType type, const char* msg);
     40 static void		printFmt		(MessageType type, const char* fmt, va_list args);
     41 static void		exitProcess		(void);
     42 
     43 void qpPrint (const char* message)
     44 {
     45 	printRaw(MESSAGETYPE_INFO, message);
     46 }
     47 
     48 void qpPrintf (const char* format, ...)
     49 {
     50 	va_list args;
     51 	va_start(args, format);
     52 	printFmt(MESSAGETYPE_INFO, format, args);
     53 	va_end(args);
     54 }
     55 
     56 void qpPrintv (const char* format, va_list args)
     57 {
     58 	printFmt(MESSAGETYPE_INFO, format, args);
     59 }
     60 
     61 void qpDief (const char* format, ...)
     62 {
     63 	va_list args;
     64 	va_start(args, format);
     65 	printFmt(MESSAGETYPE_ERROR, format, args);
     66 	va_end(args);
     67 
     68 	exitProcess();
     69 }
     70 
     71 void qpDiev (const char* format, va_list args)
     72 {
     73 	printFmt(MESSAGETYPE_ERROR, format, args);
     74 	exitProcess();
     75 }
     76 
     77 /* print() implementation. */
     78 #if (DE_OS == DE_OS_ANDROID)
     79 
     80 #include <android/log.h>
     81 
     82 static android_LogPriority getLogPriority (MessageType type)
     83 {
     84 	switch (type)
     85 	{
     86 		case MESSAGETYPE_INFO:	return ANDROID_LOG_INFO;
     87 		case MESSAGETYPE_ERROR:	return ANDROID_LOG_FATAL;
     88 		default:				return ANDROID_LOG_DEBUG;
     89 	}
     90 }
     91 
     92 void printRaw (MessageType type, const char* message)
     93 {
     94 	__android_log_write(getLogPriority(type), "dEQP", message);
     95 }
     96 
     97 void printFmt (MessageType type, const char* format, va_list args)
     98 {
     99 	__android_log_vprint(getLogPriority(type), "dEQP", format, args);
    100 }
    101 
    102 #else
    103 
    104 static FILE* getOutFile (MessageType type)
    105 {
    106 	if (type == MESSAGETYPE_ERROR)
    107 		return stderr;
    108 	else
    109 		return stdout;
    110 }
    111 
    112 void printRaw (MessageType type, const char* message)
    113 {
    114 	FILE* out = getOutFile(type);
    115 
    116 	if (type == MESSAGETYPE_ERROR)
    117 		fprintf(out, "FATAL ERROR: ");
    118 
    119 	fputs(message, out);
    120 
    121 	if (type == MESSAGETYPE_ERROR)
    122 	{
    123 		putc('\n', out);
    124 		fflush(out);
    125 	}
    126 }
    127 
    128 void printFmt (MessageType type, const char* format, va_list args)
    129 {
    130 	FILE* out = getOutFile(type);
    131 
    132 	if (type == MESSAGETYPE_ERROR)
    133 		fprintf(out, "FATAL ERROR: ");
    134 
    135 	vfprintf(out, format, args);
    136 
    137 	if (type == MESSAGETYPE_ERROR)
    138 	{
    139 		putc('\n', out);
    140 		fflush(out);
    141 	}
    142 }
    143 
    144 #endif
    145 
    146 /* exitProcess() implementation. */
    147 #if (DE_OS == DE_OS_WIN32)
    148 
    149 #define NOMINMAX
    150 #define VC_EXTRALEAN
    151 #define WIN32_LEAN_AND_MEAN
    152 #include <windows.h>
    153 
    154 static void exitProcess (void)
    155 {
    156 	/* Some API implementations register atexit() functions that may hang.
    157 	   By using TerminateProcess() we can avoid calling any potentially hanging exit routines. */
    158 	HANDLE curProc = GetCurrentProcess();
    159 	TerminateProcess(curProc, -1);
    160 }
    161 
    162 #else
    163 
    164 #if (DE_OS == DE_OS_IOS)
    165 #	include "deThread.h"	/*!< for deSleep() */
    166 #endif
    167 
    168 #if defined(QP_USE_SIGNAL_HANDLER)
    169 #	include <signal.h>
    170 #endif
    171 
    172 static void exitProcess (void)
    173 {
    174 #if (DE_OS == DE_OS_IOS)
    175 	/* Since tests are in the same process as execserver, we want to give it
    176 	   a chance to stream complete log data before terminating. */
    177 	deSleep(5000);
    178 #endif
    179 
    180 #if defined(QP_USE_SIGNAL_HANDLER)
    181 	/* QP_USE_SIGNAL_HANDLER defined, this means this function could have
    182 	   been called from a signal handler. Calling exit() inside a signal
    183 	   handler is not safe. */
    184 
    185 	/* Flush all open FILES */
    186 	fflush(DE_NULL);
    187 
    188 	/* Kill without calling any _at_exit handlers as those might hang */
    189 	raise(SIGKILL);
    190 #else
    191 	exit(-1);
    192 #endif
    193 }
    194 
    195 #endif
    196