Initial import to Tizen
[profile/ivi/sphinxbase.git] / src / libsphinxbase / util / err.c
1 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* ====================================================================
3  * Copyright (c) 1999-2004 Carnegie Mellon University.  All rights
4  * reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer. 
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * This work was supported in part by funding from the Defense Advanced 
19  * Research Projects Agency and the National Science Foundation of the 
20  * United States of America, and the CMU Sphinx Speech Consortium.
21  *
22  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
23  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
26  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * ====================================================================
35  *
36  */
37 /**
38  * @file err.c
39  * @brief Somewhat antiquated logging and error interface.
40  */
41
42 #include "config.h"
43
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <stdarg.h>
47 #include <string.h>
48 #include <errno.h>
49
50 #include "sphinxbase/err.h"
51
52 #ifdef SPHINX_DEBUG
53 static int sphinx_debug_level;
54 int
55 err_set_debug_level(int level)
56 {
57     int prev = sphinx_debug_level;
58     sphinx_debug_level = level;
59     return prev;
60 }
61 int
62 err_get_debug_level(void)
63 {
64     return sphinx_debug_level;
65 }
66 #else
67 int
68 err_set_debug_level(int level)
69 {
70     return 0;
71 }
72
73 int
74 err_get_debug_level(void)
75 {
76     return 0;
77 }
78 #endif
79
80 #if defined(HAVE_PTHREAD_H)
81 #include <pthread.h>
82 static pthread_key_t logfp_index;
83 static pthread_once_t logfp_index_once = PTHREAD_ONCE_INIT;
84
85 void
86 logfp_index_alloc(void)
87 {
88     pthread_key_create(&logfp_index, NULL);
89 }
90
91 FILE *
92 err_get_logfp(void)
93 {
94     FILE *logfp;
95
96     pthread_once(&logfp_index_once, logfp_index_alloc);
97     logfp = (FILE *)pthread_getspecific(logfp_index);
98
99     if (logfp == NULL)
100         return stderr;
101     else if (logfp == (FILE*) -1)
102         return NULL;
103     else
104         return logfp;
105 }
106
107 static void
108 internal_set_logfp(FILE *fh)
109 {
110     if (fh == NULL)
111         fh = (FILE*) -1;
112
113     pthread_setspecific(logfp_index, (void *)fh);
114 }
115
116 #elif defined(_WIN32) || defined(__CYGWIN__) /* Use Windows TLS on Cygwin */
117 #include <windows.h>
118 static DWORD logfp_index; /** TLS index for log file */
119 static LONG logfp_index_once = 0; /** True if we have initialized TLS */
120
121 void
122 logfp_index_alloc(void)
123 {
124     logfp_index = TlsAlloc();
125 }
126
127 FILE *
128 err_get_logfp(void)
129 {
130     FILE *logfp;
131
132     if (InterlockedExchange(&logfp_index_once, 1) == 0)
133         logfp_index_alloc();
134     logfp = (FILE *)TlsGetValue(logfp_index);
135
136     if (logfp == NULL)
137         return stderr;
138     else if (logfp == (FILE*) -1)
139         return NULL;
140     else
141         return logfp;
142 }
143
144 static void
145 internal_set_logfp(FILE *fh)
146 {
147     if (fh == NULL)
148         fh = (FILE*) -1;
149
150     TlsSetValue(logfp_index, (void *)fh);
151 }
152
153 #else
154 FILE *logfp = NULL;
155
156 FILE *
157 err_get_logfp(void)
158 {
159     if (logfp == NULL)
160         return stderr;
161     else if (logfp == (FILE*) -1)
162         return NULL;
163     else
164         return logfp;
165 }
166
167 static void
168 internal_set_logfp(FILE *fh)
169 {
170     if (fh == NULL)
171         fh = (FILE*) -1;
172
173     logfp = fh;
174 }
175
176 #endif
177  
178 FILE *
179 err_set_logfp(FILE *newfp)
180 {
181     FILE *oldfp;
182
183     oldfp = err_get_logfp();
184     internal_set_logfp(newfp);
185
186     return oldfp;
187 }
188
189 int
190 err_set_logfile(char const *file)
191 {
192     FILE *newfp, *oldfp;
193
194     if ((newfp = fopen(file, "a")) == NULL)
195         return -1;
196     oldfp = err_get_logfp();
197     internal_set_logfp(newfp);
198     if (oldfp != NULL && oldfp != stdout && oldfp != stderr)
199         fclose(oldfp);
200     return 0;
201 }
202
203
204 void
205 _E__pr_info_header_wofn(char const *msg)
206 {
207     FILE *logfp;
208
209     logfp = err_get_logfp();
210     if (logfp == NULL)
211         return;
212     /* make different format so as not to be parsed by emacs compile */
213     fprintf(logfp, "%s:\t", msg);
214     fflush(logfp);
215 }
216
217 void
218 _E__pr_header(char const *f, long ln, char const *msg)
219 {
220     char const *fname;
221     FILE *logfp;
222
223     logfp = err_get_logfp();
224     if (logfp == NULL)
225         return;
226     fname = strrchr(f,'\\');
227     if (fname == NULL)
228         fname = strrchr(f,'/');
229     fprintf(logfp, "%s: \"%s\", line %ld: ", msg, fname == NULL ? f : fname + 1, ln);
230     fflush(logfp);
231 }
232
233 void
234 _E__pr_info_header(char const *f, long ln, char const *msg)
235 {
236     char const *fname;
237     FILE *logfp;
238
239     logfp = err_get_logfp();
240     if (logfp == NULL)
241         return;
242     fname = strrchr(f,'\\');
243     if (fname == NULL)
244         fname = strrchr(f,'/');
245     /* make different format so as not to be parsed by emacs compile */
246     fprintf(logfp, "%s: %s(%ld): ", msg, fname == NULL ? f : fname + 1, ln);
247     fflush(logfp);
248 }
249
250 void
251 _E__pr_warn(char const *fmt, ...)
252 {
253     va_list pvar;
254     FILE *logfp;
255
256     logfp = err_get_logfp();
257     if (logfp == NULL)
258         return;
259     va_start(pvar, fmt);
260     vfprintf(logfp, fmt, pvar);
261     va_end(pvar);
262
263     fflush(logfp);
264 }
265
266 void
267 _E__pr_info(char const *fmt, ...)
268 {
269     va_list pvar;
270     FILE *logfp;
271
272     logfp = err_get_logfp();
273     if (logfp == NULL)
274         return;
275     va_start(pvar, fmt);
276     vfprintf(logfp, fmt, pvar);
277     va_end(pvar);
278
279     fflush(logfp);
280 }
281
282 void
283 _E__die_error(char const *fmt, ...)
284 {
285     va_list pvar;
286     FILE *logfp;
287
288     logfp = err_get_logfp();
289     if (logfp) {
290         va_start(pvar, fmt);
291         vfprintf(logfp, fmt, pvar);
292         va_end(pvar);
293         fflush(logfp);
294     }
295
296 #if defined(__ADSPBLACKFIN__) && !defined(__linux__)
297     while(1);
298 #else 
299         exit(-1);
300 #endif
301 }
302
303 void
304 _E__fatal_sys_error(char const *fmt, ...)
305 {
306     va_list pvar;
307     FILE *logfp;
308     int local_errno = errno;
309
310     logfp = err_get_logfp();
311     if (logfp) {
312         va_start(pvar, fmt);
313         vfprintf(logfp, fmt, pvar);
314         va_end(pvar);
315
316         fprintf(logfp, ": %s\n", strerror(local_errno));
317         fflush(logfp);
318     }
319
320
321 #if defined(__ADSPBLACKFIN__) && !defined(__linux__)
322     while(1);
323 #else 
324         exit(-1);
325 #endif
326
327 }
328
329 void
330 _E__sys_error(char const *fmt, ...)
331 {
332     va_list pvar;
333     FILE *logfp;
334     int local_errno = errno;
335
336     logfp = err_get_logfp();
337     if (logfp == NULL)
338         return;
339
340     va_start(pvar, fmt);
341     vfprintf(logfp, fmt, pvar);
342     va_end(pvar);
343
344     fprintf(logfp, "; %s\n", strerror(local_errno));
345     fflush(logfp);
346 }
347
348 void
349 _E__abort_error(char const *fmt, ...)
350 {
351     va_list pvar;
352     FILE *logfp;
353
354     logfp = err_get_logfp();
355     if (logfp) {
356         va_start(pvar, fmt);
357         vfprintf(logfp, fmt, pvar);
358         va_end(pvar);
359         fflush(logfp);
360     }
361
362 #if defined(__ADSPBLACKFIN__) && !defined(__linux__)
363 while(1);
364 #elif defined(_WIN32_WCE)
365 exit(-1);
366 #else
367 abort();
368 #endif
369
370 }