Move Windows timer utility functions from PA backend into libpbd
[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 DebugBits PBD::DEBUG::UndoHistory = PBD::new_debug_bit ("undohistory");
57 DebugBits PBD::DEBUG::Timing = PBD::new_debug_bit ("timing");
58
59 /* These are debug bits that are used by backends. Since these are loaded dynamically,
60    after command-line parsing, defining them in code that is part of the backend
61    doesn't make them available for command line parsing. Put them here.
62
63    This is sort of a hack, because it means that the debug bits aren't defined
64    with the code in which they are relevant. But providing access to debug bits
65    from dynamically loaded code, for use in command line parsing, is way above the pay grade
66    of this debug tracing scheme.
67 */
68 DebugBits PBD::DEBUG::WavesMIDI = PBD::new_debug_bit ("WavesMIDI");
69 DebugBits PBD::DEBUG::WavesAudio = PBD::new_debug_bit ("WavesAudio");
70
71 DebugBits PBD::debug_bits;
72
73 DebugBits
74 PBD::new_debug_bit (const char* name)
75 {
76         DebugBits ret;
77         ret.set (_debug_bit++, 1);
78         _debug_bit_map().insert (make_pair (name, ret));
79         return ret;
80 }
81
82 void
83 PBD::debug_print (const char* prefix, string str)
84 {
85         cerr << prefix << ": " << str;
86 }
87
88 int
89 PBD::parse_debug_options (const char* str)
90 {
91         string in_str = str;
92         typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
93         boost::char_separator<char> sep (",");
94         tokenizer tokens (in_str, sep);
95         DebugBits bits;
96
97         for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {
98                 if (*tok_iter == "list") {
99                         list_debug_options ();
100                         return 1;
101                 }
102
103                 if (*tok_iter == "all") {
104                         debug_bits.set (); /* sets all bits */
105                         return 0;
106                 }
107
108                 for (map<const char*,DebugBits>::iterator i = _debug_bit_map().begin(); i != _debug_bit_map().end(); ++i) {
109                         const char* cstr = (*tok_iter).c_str();
110
111                         if (strncasecmp (cstr, i->first, strlen (cstr)) == 0) {
112                                 bits |= i->second;
113                                 cerr << i->first << " set ... debug bits now set to " << bits << " using " << i->second << endl;
114                         }
115                 }
116         }
117         
118         debug_bits = bits;
119         
120         return 0;
121 }
122
123 void
124 PBD::list_debug_options ()
125 {
126         cout << _("The following debug options are available. Separate multiple options with commas.\nNames are case-insensitive and can be abbreviated.") << endl << endl;
127         cout << '\t' << X_("all") << endl; 
128
129         vector<string> options;
130
131         for (map<const char*,DebugBits>::iterator i = _debug_bit_map().begin(); i != _debug_bit_map().end(); ++i) {
132                 options.push_back (i->first);
133         }
134
135         sort (options.begin(), options.end());
136
137         for (vector<string>::iterator i = options.begin(); i != options.end(); ++i) {
138                 cout << "\t" << (*i) << endl;
139         }
140 }