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