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