• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	MESSAGETYPE_NONFATAL_ERROR,
36 
37 	MESSAGETYPE_LAST
38 } MessageType;
39 
40 static writePtr		writeRedirect		= 0;
41 static writeFtmPtr	writeFtmRedirect	= 0;
42 
43 static void		printRaw		(MessageType type, const char* msg);
44 static void		printFmt		(MessageType type, const char* fmt, va_list args);
45 static void		exitProcess		(void);
46 
qpRedirectOut(writePtr w,writeFtmPtr wftm)47 void qpRedirectOut (writePtr w, writeFtmPtr wftm)
48 {
49 	writeRedirect = w;
50 	writeFtmRedirect = wftm;
51 }
52 
qpPrint(const char * message)53 void qpPrint (const char* message)
54 {
55 	printRaw(MESSAGETYPE_INFO, message);
56 }
57 
qpPrintf(const char * format,...)58 void qpPrintf (const char* format, ...)
59 {
60 	va_list args;
61 	va_start(args, format);
62 	printFmt(MESSAGETYPE_INFO, format, args);
63 	va_end(args);
64 }
65 
qpPrintErrorf(const char * format,...)66 void qpPrintErrorf (const char* format, ...)
67 {
68 	va_list args;
69 	va_start(args, format);
70 	printFmt(MESSAGETYPE_NONFATAL_ERROR, format, args);
71 	va_end(args);
72 }
73 
qpPrintv(const char * format,va_list args)74 void qpPrintv (const char* format, va_list args)
75 {
76 	printFmt(MESSAGETYPE_INFO, format, args);
77 }
78 
qpPrintErrorv(const char * format,va_list args)79 void qpPrintErrorv (const char* format, va_list args)
80 {
81 	printFmt(MESSAGETYPE_NONFATAL_ERROR, format, args);
82 }
83 
qpDief(const char * format,...)84 void qpDief (const char* format, ...)
85 {
86 	va_list args;
87 	va_start(args, format);
88 	printFmt(MESSAGETYPE_ERROR, format, args);
89 	va_end(args);
90 
91 	exitProcess();
92 }
93 
qpDiev(const char * format,va_list args)94 void qpDiev (const char* format, va_list args)
95 {
96 	printFmt(MESSAGETYPE_ERROR, format, args);
97 	exitProcess();
98 }
99 
100 /* print() implementation. */
101 #if (DE_OS == DE_OS_ANDROID)
102 
103 #include <android/log.h>
104 
getLogPriority(MessageType type)105 static android_LogPriority getLogPriority (MessageType type)
106 {
107 	switch (type)
108 	{
109 		case MESSAGETYPE_INFO:	return ANDROID_LOG_INFO;
110 		case MESSAGETYPE_ERROR:	return ANDROID_LOG_FATAL;
111 		default:				return ANDROID_LOG_DEBUG;
112 	}
113 }
114 
printRaw(MessageType type,const char * message)115 void printRaw (MessageType type, const char* message)
116 {
117 	if (writeRedirect && !writeRedirect(type, message))
118 		return;
119 
120 	__android_log_write(getLogPriority(type), "dEQP", message);
121 }
122 
printFmt(MessageType type,const char * format,va_list args)123 void printFmt (MessageType type, const char* format, va_list args)
124 {
125 	if (writeFtmRedirect && !writeFtmRedirect(type, format, args))
126 		return;
127 
128 	__android_log_vprint(getLogPriority(type), "dEQP", format, args);
129 }
130 
131 #else
132 
getOutFile(MessageType type)133 static FILE* getOutFile (MessageType type)
134 {
135 	if (type == MESSAGETYPE_ERROR || type == MESSAGETYPE_NONFATAL_ERROR)
136 		return stderr;
137 	else
138 		return stdout;
139 }
140 
printRaw(MessageType type,const char * message)141 void printRaw (MessageType type, const char* message)
142 {
143 	if (writeRedirect && !writeRedirect(type, message))
144 		return;
145 
146 	FILE* out = getOutFile(type);
147 
148 	if (type == MESSAGETYPE_ERROR)
149 		fprintf(out, "FATAL ERROR: ");
150 
151 	fputs(message, out);
152 
153 	if (type == MESSAGETYPE_ERROR)
154 	{
155 		putc('\n', out);
156 		fflush(out);
157 	}
158 }
159 
printFmt(MessageType type,const char * format,va_list args)160 void printFmt (MessageType type, const char* format, va_list args)
161 {
162 	if (writeFtmRedirect && !writeFtmRedirect(type, format, args))
163 		return;
164 
165 	FILE* out = getOutFile(type);
166 
167 	if (type == MESSAGETYPE_ERROR)
168 		fprintf(out, "FATAL ERROR: ");
169 
170 	vfprintf(out, format, args);
171 
172 	if (type == MESSAGETYPE_ERROR)
173 	{
174 		putc('\n', out);
175 		fflush(out);
176 	}
177 }
178 
179 #endif
180 
181 /* exitProcess() implementation. */
182 #if (DE_OS == DE_OS_WIN32)
183 
184 #define NOMINMAX
185 #define VC_EXTRALEAN
186 #define WIN32_LEAN_AND_MEAN
187 #include <windows.h>
188 
exitProcess(void)189 static void exitProcess (void)
190 {
191 	/* Some API implementations register atexit() functions that may hang.
192 	   By using TerminateProcess() we can avoid calling any potentially hanging exit routines. */
193 	HANDLE curProc = GetCurrentProcess();
194 	TerminateProcess(curProc, -1);
195 }
196 
197 #else
198 
199 #if (DE_OS == DE_OS_IOS)
200 #	include "deThread.h"	/*!< for deSleep() */
201 #endif
202 
203 #if defined(QP_USE_SIGNAL_HANDLER)
204 #	include <signal.h>
205 #endif
206 
exitProcess(void)207 static void exitProcess (void)
208 {
209 #if (DE_OS == DE_OS_IOS)
210 	/* Since tests are in the same process as execserver, we want to give it
211 	   a chance to stream complete log data before terminating. */
212 	deSleep(5000);
213 #endif
214 
215 #if defined(QP_USE_SIGNAL_HANDLER)
216 	/* QP_USE_SIGNAL_HANDLER defined, this means this function could have
217 	   been called from a signal handler. Calling exit() inside a signal
218 	   handler is not safe. */
219 
220 	/* Flush all open FILES */
221 	fflush(DE_NULL);
222 
223 	/* Kill without calling any _at_exit handlers as those might hang */
224 	raise(SIGKILL);
225 #else
226 	exit(-1);
227 #endif
228 }
229 
230 #endif
231