blob: 15d8ac87056d650a39de5e12c54cfef9484b716d [file] [log] [blame]
Chia-I Wu8e270b52015-01-03 14:47:32 +08001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28#include <stdlib.h>
29#include <stdio.h>
30#include "icd-log.h"
31
32struct icd_logger_callback {
33 XGL_DBG_MSG_CALLBACK_FUNCTION func;
34 XGL_VOID *user_data;
35
36 struct icd_logger_callback *next;
37};
38
39struct icd_logger {
40 bool debug_echo_enable;
41 bool break_on_error;
42 bool break_on_warning;
43
44 struct icd_logger_callback *callbacks;
45};
46
47static struct icd_logger icd_logger;
48
49XGL_RESULT icd_logger_set_bool(XGL_DBG_GLOBAL_OPTION option, bool enable)
50{
51 XGL_RESULT res = XGL_SUCCESS;
52
53 switch (option) {
54 case XGL_DBG_OPTION_DEBUG_ECHO_ENABLE:
55 icd_logger.debug_echo_enable = enable;
56 break;
57 case XGL_DBG_OPTION_BREAK_ON_ERROR:
58 icd_logger.break_on_error = enable;
59 break;
60 case XGL_DBG_OPTION_BREAK_ON_WARNING:
61 icd_logger.break_on_warning = enable;
62 break;
63 default:
64 res = XGL_ERROR_INVALID_VALUE;
65 break;
66 }
67
68 return res;
69}
70
71XGL_RESULT icd_logger_add_callback(XGL_DBG_MSG_CALLBACK_FUNCTION func,
72 void *user_data)
73{
74 struct icd_logger_callback *cb;
75
76 /* use malloc() as allocator may not be initialized yet */
77 cb = malloc(sizeof(*cb));
78 if (!cb)
79 return XGL_ERROR_OUT_OF_MEMORY;
80
81 cb->func = func;
82 cb->user_data = user_data;
83
84 cb->next = icd_logger.callbacks;
85 icd_logger.callbacks = cb;
86
87 return XGL_SUCCESS;
88}
89
90XGL_RESULT icd_logger_remove_callback(XGL_DBG_MSG_CALLBACK_FUNCTION func)
91{
92 struct icd_logger_callback *cb = icd_logger.callbacks;
93 bool found = false;
94
95 /* remove all matches */
96 while (cb) {
97 struct icd_logger_callback *next = cb->next;
98
99 if (cb->func == func) {
100 free(cb);
101 found = true;
102 }
103
104 cb = next;
105 }
106
107 return (found) ? XGL_SUCCESS : XGL_ERROR_INVALID_POINTER;
108}
109
110void icd_logger_clear_callbacks(void)
111{
112 struct icd_logger_callback *cb = icd_logger.callbacks;
113
114 while (cb) {
115 struct icd_logger_callback *next = cb->next;
116 free(cb);
117 cb = next;
118 }
119
120 icd_logger.callbacks = NULL;
121}
122
123static void icd_log_str(XGL_DBG_MSG_TYPE msg_type,
124 XGL_VALIDATION_LEVEL validation_level,
125 XGL_BASE_OBJECT src_object,
126 size_t location, int32_t msg_code,
127 const char *msg)
128{
129 const struct icd_logger_callback *cb = icd_logger.callbacks;
130
131 if (icd_logger.debug_echo_enable || !cb) {
132 fputs(msg, stderr);
133 fputc('\n', stderr);
134 }
135
136 while (cb) {
137 cb->func(msg_type, XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE, 0,
138 msg_code, msg, cb->user_data);
139 cb = cb->next;
140 }
141
142 switch (msg_type) {
143 case XGL_DBG_MSG_ERROR:
144 if (icd_logger.break_on_error)
145 abort();
146 /* fall through */
147 case XGL_DBG_MSG_WARNING:
148 if (icd_logger.break_on_warning)
149 abort();
150 break;
151 default:
152 break;
153 }
154}
155
156void icd_logv(XGL_DBG_MSG_TYPE msg_type,
157 XGL_VALIDATION_LEVEL validation_level,
158 XGL_BASE_OBJECT src_object,
159 size_t location, int32_t msg_code,
160 const char *format, va_list ap)
161{
162 char msg[256];
163 int ret;
164
165 ret = vsnprintf(msg, sizeof(msg), format, ap);
166 if (ret >= sizeof(msg) || ret < 0)
167 msg[sizeof(msg) - 1] = '\0';
168
169 icd_log_str(msg_type, validation_level, src_object,
170 location, msg_code, msg);
171}
172
173void icd_log(XGL_DBG_MSG_TYPE msg_type,
174 XGL_VALIDATION_LEVEL validation_level,
175 XGL_BASE_OBJECT src_object,
176 size_t location, int32_t msg_code,
177 const char *format, ...)
178{
179 va_list ap;
180
181 va_start(ap, format);
182 icd_logv(msg_type, validation_level, src_object,
183 location, msg_code, format, ap);
184 va_end(ap);
185}