1/*
2 $License:
3   Copyright 2011 InvenSense, Inc.
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16  $
17 */
18
19/*
20 * This file incorporates work covered by the following copyright and
21 * permission notice:
22 *
23 * Copyright (C) 2005 The Android Open Source Project
24 *
25 * Licensed under the Apache License, Version 2.0 (the "License");
26 * you may not use this file except in compliance with the License.
27 * You may obtain a copy of the License at
28 *
29 *      http://www.apache.org/licenses/LICENSE-2.0
30 *
31 * Unless required by applicable law or agreed to in writing, software
32 * distributed under the License is distributed on an "AS IS" BASIS,
33 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34 * See the License for the specific language governing permissions and
35 * limitations under the License.
36 */
37
38/*
39 * C/C++ logging functions.  See the logging documentation for API details.
40 *
41 * We'd like these to be available from C code (in case we import some from
42 * somewhere), so this has a C interface.
43 *
44 * The output will be correct when the log file is shared between multiple
45 * threads and/or multiple processes so long as the operating system
46 * supports O_APPEND.  These calls have mutex-protected data structures
47 * and so are NOT reentrant.  Do not use MPL_LOG in a signal handler.
48 */
49#ifndef _LIBS_CUTILS_MPL_LOG_H
50#define _LIBS_CUTILS_MPL_LOG_H
51
52#include "mltypes.h"
53#include <stdarg.h>
54
55#ifdef ANDROID
56#ifdef NDK_BUILD
57#include "log_macros.h"
58#else
59#include <utils/Log.h>		/* For the LOG macro */
60#endif
61#endif
62
63#ifdef __KERNEL__
64#include <linux/kernel.h>
65#endif
66
67#ifdef __cplusplus
68extern "C" {
69#endif
70
71/* --------------------------------------------------------------------- */
72
73/*
74 * Normally we strip MPL_LOGV (VERBOSE messages) from release builds.
75 * You can modify this (for example with "#define MPL_LOG_NDEBUG 0"
76 * at the top of your source file) to change that behavior.
77 */
78#ifndef MPL_LOG_NDEBUG
79#ifdef NDEBUG
80#define MPL_LOG_NDEBUG 1
81#else
82#define MPL_LOG_NDEBUG 0
83#endif
84#endif
85
86#ifdef __KERNEL__
87#define MPL_LOG_UNKNOWN MPL_LOG_VERBOSE
88#define MPL_LOG_DEFAULT KERN_DEFAULT
89#define MPL_LOG_VERBOSE KERN_CONT
90#define MPL_LOG_DEBUG   KERN_NOTICE
91#define MPL_LOG_INFO    KERN_INFO
92#define MPL_LOG_WARN    KERN_WARNING
93#define MPL_LOG_ERROR   KERN_ERR
94#define MPL_LOG_SILENT  MPL_LOG_VERBOSE
95
96#else
97	/* Based off the log priorities in android
98	   /system/core/include/android/log.h */
99#define MPL_LOG_UNKNOWN		(0)
100#define MPL_LOG_DEFAULT		(1)
101#define MPL_LOG_VERBOSE		(2)
102#define MPL_LOG_DEBUG		(3)
103#define MPL_LOG_INFO		(4)
104#define MPL_LOG_WARN		(5)
105#define MPL_LOG_ERROR		(6)
106#define MPL_LOG_SILENT		(8)
107#endif
108
109
110/*
111 * This is the local tag used for the following simplified
112 * logging macros.  You can change this preprocessor definition
113 * before using the other macros to change the tag.
114 */
115#ifndef MPL_LOG_TAG
116#ifdef __KERNEL__
117#define MPL_LOG_TAG
118#else
119#define MPL_LOG_TAG NULL
120#endif
121#endif
122
123/* --------------------------------------------------------------------- */
124
125/*
126 * Simplified macro to send a verbose log message using the current MPL_LOG_TAG.
127 */
128#ifndef MPL_LOGV
129#if MPL_LOG_NDEBUG
130#define MPL_LOGV(fmt, ...)						\
131	do {								\
132		if (0)							\
133			MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__);\
134	} while (0)
135#else
136#define MPL_LOGV(fmt, ...) MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__)
137#endif
138#endif
139
140#ifndef CONDITION
141#define CONDITION(cond)     ((cond) != 0)
142#endif
143
144#ifndef MPL_LOGV_IF
145#if MPL_LOG_NDEBUG
146#define MPL_LOGV_IF(cond, fmt, ...)  \
147	do { if (0) MPL_LOG(fmt, ##__VA_ARGS__); } while (0)
148#else
149#define MPL_LOGV_IF(cond, fmt, ...) \
150	((CONDITION(cond))						\
151		? MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \
152		: (void)0)
153#endif
154#endif
155
156/*
157 * Simplified macro to send a debug log message using the current MPL_LOG_TAG.
158 */
159#ifndef MPL_LOGD
160#define MPL_LOGD(fmt, ...) MPL_LOG(LOG_DEBUG, MPL_LOG_TAG, fmt, ##__VA_ARGS__)
161#endif
162
163#ifndef MPL_LOGD_IF
164#define MPL_LOGD_IF(cond, fmt, ...) \
165	((CONDITION(cond))					       \
166		? MPL_LOG(LOG_DEBUG, MPL_LOG_TAG, fmt, ##__VA_ARGS__)  \
167		: (void)0)
168#endif
169
170/*
171 * Simplified macro to send an info log message using the current MPL_LOG_TAG.
172 */
173#ifndef MPL_LOGI
174#define MPL_LOGI(fmt, ...) MPL_LOG(LOG_INFO, MPL_LOG_TAG, fmt, ##__VA_ARGS__)
175#endif
176
177#ifndef MPL_LOGI_IF
178#define MPL_LOGI_IF(cond, fmt, ...) \
179	((CONDITION(cond))                                              \
180		? MPL_LOG(LOG_INFO, MPL_LOG_TAG, fmt, ##__VA_ARGS__)   \
181		: (void)0)
182#endif
183
184/*
185 * Simplified macro to send a warning log message using the current MPL_LOG_TAG.
186 */
187#ifndef MPL_LOGW
188#ifdef __KERNEL__
189#define MPL_LOGW(fmt, ...) printk(KERN_WARNING MPL_LOG_TAG fmt, ##__VA_ARGS__)
190#else
191#define MPL_LOGW(fmt, ...) MPL_LOG(LOG_WARN, MPL_LOG_TAG, fmt, ##__VA_ARGS__)
192#endif
193#endif
194
195#ifndef MPL_LOGW_IF
196#define MPL_LOGW_IF(cond, fmt, ...) \
197	((CONDITION(cond))					       \
198		? MPL_LOG(LOG_WARN, MPL_LOG_TAG, fmt, ##__VA_ARGS__)   \
199		: (void)0)
200#endif
201
202/*
203 * Simplified macro to send an error log message using the current MPL_LOG_TAG.
204 */
205#ifndef MPL_LOGE
206#ifdef __KERNEL__
207#define MPL_LOGE(fmt, ...) printk(KERN_ERR MPL_LOG_TAG fmt, ##__VA_ARGS__)
208#else
209#define MPL_LOGE(fmt, ...) MPL_LOG(LOG_ERROR, MPL_LOG_TAG, fmt, ##__VA_ARGS__)
210#endif
211#endif
212
213#ifndef MPL_LOGE_IF
214#define MPL_LOGE_IF(cond, fmt, ...) \
215	((CONDITION(cond))					       \
216		? MPL_LOG(LOG_ERROR, MPL_LOG_TAG, fmt, ##__VA_ARGS__)  \
217		: (void)0)
218#endif
219
220/* --------------------------------------------------------------------- */
221
222/*
223 * Log a fatal error.  If the given condition fails, this stops program
224 * execution like a normal assertion, but also generating the given message.
225 * It is NOT stripped from release builds.  Note that the condition test
226 * is -inverted- from the normal assert() semantics.
227 */
228#define MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ...) \
229	((CONDITION(cond))					   \
230		? ((void)android_printAssert(#cond, MPL_LOG_TAG,   \
231						fmt, ##__VA_ARGS__))	\
232		: (void)0)
233
234#define MPL_LOG_ALWAYS_FATAL(fmt, ...) \
235	(((void)android_printAssert(NULL, MPL_LOG_TAG, fmt, ##__VA_ARGS__)))
236
237/*
238 * Versions of MPL_LOG_ALWAYS_FATAL_IF and MPL_LOG_ALWAYS_FATAL that
239 * are stripped out of release builds.
240 */
241#if MPL_LOG_NDEBUG
242#define MPL_LOG_FATAL_IF(cond, fmt, ...)				\
243	do {								\
244		if (0)							\
245			MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ##__VA_ARGS__); \
246	} while (0)
247#define MPL_LOG_FATAL(fmt, ...)						\
248	do {								\
249		if (0)							\
250			MPL_LOG_ALWAYS_FATAL(fmt, ##__VA_ARGS__)	\
251	} while (0)
252#else
253#define MPL_LOG_FATAL_IF(cond, fmt, ...) \
254	MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ##__VA_ARGS__)
255#define MPL_LOG_FATAL(fmt, ...) \
256	MPL_LOG_ALWAYS_FATAL(fmt, ##__VA_ARGS__)
257#endif
258
259/*
260 * Assertion that generates a log message when the assertion fails.
261 * Stripped out of release builds.  Uses the current MPL_LOG_TAG.
262 */
263#define MPL_LOG_ASSERT(cond, fmt, ...)			\
264	MPL_LOG_FATAL_IF(!(cond), fmt, ##__VA_ARGS__)
265
266/* --------------------------------------------------------------------- */
267
268/*
269 * Basic log message macro.
270 *
271 * Example:
272 *  MPL_LOG(MPL_LOG_WARN, NULL, "Failed with error %d", errno);
273 *
274 * The second argument may be NULL or "" to indicate the "global" tag.
275 */
276#ifndef MPL_LOG
277#define MPL_LOG(priority, tag, fmt, ...)		\
278	MPL_LOG_PRI(priority, tag, fmt, ##__VA_ARGS__)
279#endif
280
281/*
282 * Log macro that allows you to specify a number for the priority.
283 */
284#ifndef MPL_LOG_PRI
285#ifdef ANDROID
286#define MPL_LOG_PRI(priority, tag, fmt, ...) \
287        ALOG(priority, tag, fmt, ##__VA_ARGS__)
288#elif defined __KERNEL__
289#define MPL_LOG_PRI(priority, tag, fmt, ...) \
290	pr_debug(MPL_##priority tag fmt, ##__VA_ARGS__)
291#else
292#define MPL_LOG_PRI(priority, tag, fmt, ...) \
293	_MLPrintLog(MPL_##priority, tag, fmt, ##__VA_ARGS__)
294#endif
295#endif
296
297/*
298 * Log macro that allows you to pass in a varargs ("args" is a va_list).
299 */
300#ifndef MPL_LOG_PRI_VA
301#ifdef ANDROID
302#define MPL_LOG_PRI_VA(priority, tag, fmt, args) \
303	android_vprintLog(priority, NULL, tag, fmt, args)
304#elif defined __KERNEL__
305/* not allowed in the Kernel because there is no dev_dbg that takes a va_list */
306#else
307#define MPL_LOG_PRI_VA(priority, tag, fmt, args) \
308	_MLPrintVaLog(priority, NULL, tag, fmt, args)
309#endif
310#endif
311
312/* --------------------------------------------------------------------- */
313
314/*
315 * ===========================================================================
316 *
317 * The stuff in the rest of this file should not be used directly.
318 */
319
320#ifndef ANDROID
321int _MLPrintLog(int priority, const char *tag, const char *fmt,	...);
322int _MLPrintVaLog(int priority, const char *tag, const char *fmt, va_list args);
323/* Final implementation of actual writing to a character device */
324int _MLWriteLog(const char *buf, int buflen);
325#endif
326
327static inline void __print_result_location(int result,
328					   const char *file,
329					   const char *func, int line)
330{
331	MPL_LOGE("%s|%s|%d returning %d\n", file, func, line, result);
332}
333
334#define LOG_RESULT_LOCATION(condition) \
335	do {								\
336		__print_result_location((int)(condition), __FILE__,	\
337					__func__, __LINE__);		\
338	} while (0)
339
340
341#ifdef __cplusplus
342}
343#endif
344#endif				/* _LIBS_CUTILS_MPL_LOG_H */
345