1 /*
2  Copyright (C) 2001 Paul Davis
3  Copyright (C) 2004-2008 Grame
4  Copyright (C) 2008 Nedko Arnaudov
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published by
8  the Free Software Foundation; either version 2.1 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 
20  */
21 
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include "JackError.h"
25 #include "JackGlobals.h"
26 #include "JackMessageBuffer.h"
27 
28 using namespace Jack;
29 
change_thread_log_function(jack_log_function_t log_function)30 static bool change_thread_log_function(jack_log_function_t log_function)
31 {
32     return (jack_tls_get(JackGlobals::fKeyLogFunction) == NULL
33             && jack_tls_set(JackGlobals::fKeyLogFunction, (void*)log_function));
34 }
35 
set_threaded_log_function()36 SERVER_EXPORT int set_threaded_log_function()
37 {
38     return change_thread_log_function(JackMessageBufferAdd);
39 }
40 
jack_log_function(int level,const char * message)41 void jack_log_function(int level, const char *message)
42 {
43     void (* log_callback)(const char *);
44 
45     switch (level)
46     {
47     case LOG_LEVEL_INFO:
48         log_callback = jack_info_callback;
49         break;
50     case LOG_LEVEL_ERROR:
51         log_callback = jack_error_callback;
52         break;
53     default:
54         return;
55     }
56 
57     log_callback(message);
58 }
59 
jack_format_and_log(int level,const char * prefix,const char * fmt,va_list ap)60 static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap)
61 {
62     char buffer[256];
63     size_t len;
64     jack_log_function_t log_function;
65 
66     if (prefix != NULL) {
67         len = strlen(prefix);
68         assert(len < 256);
69         memcpy(buffer, prefix, len);
70     } else {
71         len = 0;
72     }
73 
74     vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap);
75 
76     log_function = (jack_log_function_t)jack_tls_get(JackGlobals::fKeyLogFunction);
77 
78     /* if log function is not overridden for thread, use default one */
79     if (log_function == NULL)
80     {
81         log_function = jack_log_function;
82         //log_function(LOG_LEVEL_INFO, "------ Using default log function");
83     }
84     else
85     {
86         //log_function(LOG_LEVEL_INFO, "++++++ Using thread-specific log function");
87     }
88 
89     log_function(level, buffer);
90 }
91 
jack_error(const char * fmt,...)92 SERVER_EXPORT void jack_error(const char *fmt, ...)
93 {
94 	va_list ap;
95 	va_start(ap, fmt);
96 	jack_format_and_log(LOG_LEVEL_ERROR, NULL, fmt, ap);
97 	va_end(ap);
98 }
99 
jack_info(const char * fmt,...)100 SERVER_EXPORT void jack_info(const char *fmt, ...)
101 {
102 	va_list ap;
103 	va_start(ap, fmt);
104 	jack_format_and_log(LOG_LEVEL_INFO, NULL, fmt, ap);
105 	va_end(ap);
106 }
107 
jack_log(const char * fmt,...)108 SERVER_EXPORT void jack_log(const char *fmt,...)
109 {
110 	if (JackGlobals::fVerbose) {
111 		va_list ap;
112 		va_start(ap, fmt);
113         jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap);
114 		va_end(ap);
115 	}
116 }
117 
default_jack_error_callback(const char * desc)118 SERVER_EXPORT void default_jack_error_callback(const char *desc)
119 {
120     fprintf(stderr, "%s\n", desc);
121     fflush(stderr);
122 }
123 
default_jack_info_callback(const char * desc)124 SERVER_EXPORT void default_jack_info_callback(const char *desc)
125 {
126     fprintf(stdout, "%s\n", desc);
127     fflush(stdout);
128 }
129 
silent_jack_error_callback(const char * desc)130 SERVER_EXPORT void silent_jack_error_callback(const char *desc)
131 {}
132 
silent_jack_info_callback(const char * desc)133 SERVER_EXPORT void silent_jack_info_callback(const char *desc)
134 {}
135 
136 SERVER_EXPORT void (*jack_error_callback)(const char *desc) = &default_jack_error_callback;
137 SERVER_EXPORT void (*jack_info_callback)(const char *desc) = &default_jack_info_callback;
138