1 /*
2 * Copyright 2008-2013 Various Authors
3 * Copyright 2004-2005 Timo Hirvonen
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "debug.h"
20 #include "prog.h"
21
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <sys/time.h>
26
27 #if DEBUG > 1
28 static FILE *debug_stream = NULL;
29 #endif
30
debug_init(void)31 void debug_init(void)
32 {
33 #if DEBUG > 1
34 char filename[512];
35 const char *dir = getenv("CMUS_HOME");
36
37 if (!dir || !dir[0]) {
38 dir = getenv("HOME");
39 if (!dir)
40 die("error: environment variable HOME not set\n");
41 }
42 snprintf(filename, sizeof(filename), "%s/cmus-debug.txt", dir);
43
44 debug_stream = fopen(filename, "w");
45 if (debug_stream == NULL)
46 die_errno("error opening `%s' for writing", filename);
47 #endif
48 }
49
50 /* This function must be defined even if debugging is disabled in the program
51 * because debugging might still be enabled in some plugin.
52 */
_debug_bug(const char * function,const char * fmt,...)53 void _debug_bug(const char *function, const char *fmt, ...)
54 {
55 const char *format = "\n%s: BUG: ";
56 va_list ap;
57
58 /* debug_stream exists only if debugging is enabled */
59 #if DEBUG > 1
60 fprintf(debug_stream, format, function);
61 va_start(ap, fmt);
62 vfprintf(debug_stream, fmt, ap);
63 va_end(ap);
64 #endif
65
66 /* always print bug message to stderr */
67 fprintf(stderr, format, function);
68 va_start(ap, fmt);
69 vfprintf(stderr, fmt, ap);
70 va_end(ap);
71 exit(127);
72 }
73
_debug_print(const char * function,const char * fmt,...)74 void _debug_print(const char *function, const char *fmt, ...)
75 {
76 #if DEBUG > 1
77 va_list ap;
78
79 fprintf(debug_stream, "%s: ", function);
80 va_start(ap, fmt);
81 vfprintf(debug_stream, fmt, ap);
82 va_end(ap);
83 fflush(debug_stream);
84 #endif
85 }
86
timer_get(void)87 uint64_t timer_get(void)
88 {
89 #if DEBUG > 1
90 struct timeval tv;
91
92 gettimeofday(&tv, NULL);
93 return tv.tv_sec * 1e6L + tv.tv_usec;
94 #else
95 return 0;
96 #endif
97 }
98
timer_print(const char * what,uint64_t usec)99 void timer_print(const char *what, uint64_t usec)
100 {
101 #if DEBUG > 1
102 uint64_t a = usec / 1e6;
103 uint64_t b = usec - a * 1e6;
104
105 _debug_print("TIMER", "%s: %11u.%06u\n", what, (unsigned int)a, (unsigned int)b);
106 #endif
107 }
108