2010-03-01 19:00:00 -05:00
/*
Copyright ( C ) 2009 Paul Davis
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <map>
2012-01-08 11:38:49 -05:00
# include <vector>
# include <algorithm>
2010-03-01 19:00:00 -05:00
2013-07-11 12:36:16 -04:00
# include <boost/tokenizer.hpp>
2010-03-01 19:00:00 -05:00
# include "pbd/debug.h"
# include "i18n.h"
using namespace std ;
2015-06-12 18:14:09 -04:00
using PBD : : DebugBits ;
2013-03-20 17:18:55 -04:00
2015-06-12 18:14:09 -04:00
static uint64_t _debug_bit = 0 ;
typedef std : : map < const char * , DebugBits > DebugMap ;
2013-03-20 17:18:55 -04:00
namespace PBD {
2013-03-24 15:18:20 -04:00
DebugMap & _debug_bit_map ( )
{
static DebugMap map ;
return map ;
}
2013-03-20 17:18:55 -04:00
}
2010-03-01 19:00:00 -05:00
2015-06-12 18:14:09 -04:00
DebugBits PBD : : DEBUG : : Stateful = PBD : : new_debug_bit ( " stateful " ) ;
DebugBits PBD : : DEBUG : : Properties = PBD : : new_debug_bit ( " properties " ) ;
DebugBits PBD : : DEBUG : : FileManager = PBD : : new_debug_bit ( " filemanager " ) ;
DebugBits PBD : : DEBUG : : Pool = PBD : : new_debug_bit ( " pool " ) ;
DebugBits PBD : : DEBUG : : EventLoop = PBD : : new_debug_bit ( " eventloop " ) ;
DebugBits PBD : : DEBUG : : AbstractUI = PBD : : new_debug_bit ( " abstractui " ) ;
DebugBits PBD : : DEBUG : : FileUtils = PBD : : new_debug_bit ( " fileutils " ) ;
DebugBits PBD : : DEBUG : : Configuration = PBD : : new_debug_bit ( " configuration " ) ;
2015-08-18 23:41:19 -04:00
DebugBits PBD : : DEBUG : : UndoHistory = PBD : : new_debug_bit ( " undohistory " ) ;
2015-09-12 07:41:00 -04:00
DebugBits PBD : : DEBUG : : Timing = PBD : : new_debug_bit ( " timing " ) ;
2015-09-13 22:22:39 -04:00
DebugBits PBD : : DEBUG : : Threads = PBD : : new_debug_bit ( " threads " ) ;
2010-03-01 19:00:00 -05:00
2015-05-13 19:37:15 -04:00
/* These are debug bits that are used by backends. Since these are loaded dynamically,
after command - line parsing , defining them in code that is part of the backend
doesn ' t make them available for command line parsing . Put them here .
This is sort of a hack , because it means that the debug bits aren ' t defined
with the code in which they are relevant . But providing access to debug bits
from dynamically loaded code , for use in command line parsing , is way above the pay grade
of this debug tracing scheme .
*/
DebugBits PBD : : DEBUG : : WavesMIDI = PBD : : new_debug_bit ( " WavesMIDI " ) ;
DebugBits PBD : : DEBUG : : WavesAudio = PBD : : new_debug_bit ( " WavesAudio " ) ;
2015-06-12 18:14:09 -04:00
DebugBits PBD : : debug_bits ;
2010-03-01 19:00:00 -05:00
2015-06-12 18:14:09 -04:00
DebugBits
2010-03-01 19:00:00 -05:00
PBD : : new_debug_bit ( const char * name )
{
2015-10-15 08:59:11 -04:00
DebugBits ret ;
DebugMap : : iterator i = _debug_bit_map ( ) . find ( name ) ;
if ( i ! = _debug_bit_map ( ) . end ( ) ) {
return i - > second ;
}
if ( _debug_bit > = debug_bits . size ( ) ) {
cerr < < " Too many debug bits defined, offender was " < < name < < endl ;
abort ( ) ;
/*NOTREACHED*/
}
ret . set ( _debug_bit + + , 1 ) ;
_debug_bit_map ( ) . insert ( make_pair ( name , ret ) ) ;
2010-03-01 19:00:00 -05:00
return ret ;
}
void
PBD : : debug_print ( const char * prefix , string str )
{
2015-09-21 17:08:45 -04:00
cout < < prefix < < " : " < < str ;
2010-03-01 19:00:00 -05:00
}
int
PBD : : parse_debug_options ( const char * str )
{
2014-04-14 15:26:48 -04:00
string in_str = str ;
2013-07-11 12:36:16 -04:00
typedef boost : : tokenizer < boost : : char_separator < char > > tokenizer ;
boost : : char_separator < char > sep ( " , " ) ;
2014-04-14 15:26:48 -04:00
tokenizer tokens ( in_str , sep ) ;
2015-06-12 18:14:09 -04:00
DebugBits bits ;
2010-03-01 19:00:00 -05:00
2013-07-11 12:36:16 -04:00
for ( tokenizer : : iterator tok_iter = tokens . begin ( ) ; tok_iter ! = tokens . end ( ) ; + + tok_iter ) {
if ( * tok_iter = = " list " ) {
2010-03-01 19:00:00 -05:00
list_debug_options ( ) ;
return 1 ;
}
2013-07-11 12:36:16 -04:00
if ( * tok_iter = = " all " ) {
2015-06-12 18:14:09 -04:00
debug_bits . set ( ) ; /* sets all bits */
2010-03-01 19:00:00 -05:00
return 0 ;
}
2015-06-12 18:14:09 -04:00
for ( map < const char * , DebugBits > : : iterator i = _debug_bit_map ( ) . begin ( ) ; i ! = _debug_bit_map ( ) . end ( ) ; + + i ) {
2013-07-11 12:36:16 -04:00
const char * cstr = ( * tok_iter ) . c_str ( ) ;
if ( strncasecmp ( cstr , i - > first , strlen ( cstr ) ) = = 0 ) {
2015-06-12 18:14:09 -04:00
bits | = i - > second ;
2015-09-21 17:08:45 -04:00
cout < < i - > first < < " set ... debug bits now set to " < < bits < < " using " < < i - > second < < endl ;
2010-03-01 19:00:00 -05:00
}
}
}
2015-10-05 10:17:49 -04:00
2015-06-12 18:14:09 -04:00
debug_bits = bits ;
2015-10-05 10:17:49 -04:00
2010-03-01 19:00:00 -05:00
return 0 ;
}
void
PBD : : list_debug_options ( )
{
2012-01-08 20:59:52 -05:00
cout < < _ ( " The following debug options are available. Separate multiple options with commas. \n Names are case-insensitive and can be abbreviated. " ) < < endl < < endl ;
2015-10-04 14:51:05 -04:00
cout < < ' \t ' < < X_ ( " all " ) < < endl ;
2012-01-08 11:38:49 -05:00
vector < string > options ;
2010-03-01 19:00:00 -05:00
2015-06-12 18:14:09 -04:00
for ( map < const char * , DebugBits > : : iterator i = _debug_bit_map ( ) . begin ( ) ; i ! = _debug_bit_map ( ) . end ( ) ; + + i ) {
2012-01-08 11:38:49 -05:00
options . push_back ( i - > first ) ;
2010-03-01 19:00:00 -05:00
}
2012-01-08 11:38:49 -05:00
sort ( options . begin ( ) , options . end ( ) ) ;
for ( vector < string > : : iterator i = options . begin ( ) ; i ! = options . end ( ) ; + + i ) {
cout < < " \t " < < ( * i ) < < endl ;
}
2010-03-01 19:00:00 -05:00
}