add PBD::DEBUG bits for WavesAudio and WavesMIDI
[ardour.git] / libs / pbd / debug.cc
1 /*
2     Copyright (C) 2009 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <cstring>
21 #include <cstdlib>
22 #include <iostream>
23 #include <map>
24 #include <vector>
25 #include <algorithm>
26
27 #include <boost/tokenizer.hpp>
28
29 #include "pbd/debug.h"
30
31 #include "i18n.h"
32
33 using namespace std;
34 using PBD::DebugBits;
35
36 static uint64_t _debug_bit = 0;
37
38 typedef std::map<const char*,DebugBits> DebugMap;
39
40 namespace PBD {
41         DebugMap & _debug_bit_map()
42         {
43                 static DebugMap map;
44                 return map;
45         }
46 }
47
48 DebugBits PBD::DEBUG::Stateful = PBD::new_debug_bit ("stateful");
49 DebugBits PBD::DEBUG::Properties = PBD::new_debug_bit ("properties");
50 DebugBits PBD::DEBUG::FileManager = PBD::new_debug_bit ("filemanager");
51 DebugBits PBD::DEBUG::Pool = PBD::new_debug_bit ("pool");
52 DebugBits PBD::DEBUG::EventLoop = PBD::new_debug_bit ("eventloop");
53 DebugBits PBD::DEBUG::AbstractUI = PBD::new_debug_bit ("abstractui");
54 DebugBits PBD::DEBUG::FileUtils = PBD::new_debug_bit ("fileutils");
55 DebugBits PBD::DEBUG::Configuration = PBD::new_debug_bit ("configuration");
56
57 /* These are debug bits that are used by backends. Since these are loaded dynamically,
58    after command-line parsing, defining them in code that is part of the backend
59    doesn't make them available for command line parsing. Put them here.
60
61    This is sort of a hack, because it means that the debug bits aren't defined
62    with the code in which they are relevant. But providing access to debug bits
63    from dynamically loaded code, for use in command line parsing, is way above the pay grade
64    of this debug tracing scheme.
65 */
66
67 DebugBits PBD::DEBUG::WavesMIDI = PBD::new_debug_bit ("WavesMIDI");
68 DebugBits PBD::DEBUG::WavesAudio = PBD::new_debug_bit ("WavesAudio");
69
70 DebugBits PBD::debug_bits;
71
72 DebugBits
73 PBD::new_debug_bit (const char* name)
74 {
75         DebugBits ret;
76         ret.set (_debug_bit++, 1);
77         _debug_bit_map().insert (make_pair (name, ret));
78         return ret;
79 }
80
81 void
82 PBD::debug_print (const char* prefix, string str)
83 {
84         cerr << prefix << ": " << str;
85 }
86
87 int
88 PBD::parse_debug_options (const char* str)
89 {
90         string in_str = str;
91         typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
92         boost::char_separator<char> sep (",");
93         tokenizer tokens (in_str, sep);
94         DebugBits bits;
95
96         for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {
97                 if (*tok_iter == "list") {
98                         list_debug_options ();
99                         return 1;
100                 }
101
102                 if (*tok_iter == "all") {
103                         debug_bits.set (); /* sets all bits */
104                         return 0;
105                 }
106
107                 for (map<const char*,DebugBits>::iterator i = _debug_bit_map().begin(); i != _debug_bit_map().end(); ++i) {
108                         const char* cstr = (*tok_iter).c_str();
109
110                         if (strncasecmp (cstr, i->first, strlen (cstr)) == 0) {
111                                 bits |= i->second;
112                                 cerr << i->first << " set ... debug bits now set to " << bits << " using " << i->second << endl;
113                         }
114                 }
115         }
116         
117         debug_bits = bits;
118         
119         return 0;
120 }
121
122 void
123 PBD::list_debug_options ()
124 {
125         cout << _("The following debug options are available. Separate multiple options with commas.\nNames are case-insensitive and can be abbreviated.") << endl << endl;
126         cout << '\t' << X_("all") << endl; 
127
128         vector<string> options;
129
130         for (map<const char*,DebugBits>::iterator i = _debug_bit_map().begin(); i != _debug_bit_map().end(); ++i) {
131                 options.push_back (i->first);
132         }
133
134         sort (options.begin(), options.end());
135
136         for (vector<string>::iterator i = options.begin(); i != options.end(); ++i) {
137                 cout << "\t" << (*i) << endl;
138         }
139 }