cverb.cpp revision cc2ee177dbb3befca43e36cfc56778b006c3d050
1/** 2 * @file cverb.cpp 3 * verbose output stream 4 * 5 * @remark Copyright 2002, 2004 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author Philippe Elie 9 * @author John Levon 10 */ 11 12#include <fstream> 13#include <iostream> 14#include <map> 15#include <string> 16 17#include "cverb.h" 18 19using namespace std; 20 21cverb_object cverb; 22verbose vlevel1("level1"); 23verbose vdebug("debug"); 24verbose vstats("stats"); 25verbose vsfile("sfile"); 26 27namespace { 28 29// The right way is to use: ofstream fout; but cverb(fout.rdbuf()) receive 30// a null pointer and stl shipped with 2.91 segfault. 31ofstream fout("/dev/null"); 32ostream null_stream(fout.rdbuf()); 33 34// Used to setup the bad bit in our null stream so output will fail earlier 35// and overhead will be smaller. 36struct setup_stream { 37 setup_stream(); 38}; 39 40setup_stream::setup_stream() 41{ 42 null_stream.clear(ios::badbit); 43} 44 45setup_stream setup; 46 47// We use a multimap because user can create multiple verbose object with 48// the same name, these are synonymous, setting up one to true will setup 49// all with the same name to true. 50typedef multimap<string, verbose *> recorder_t; 51// The recorder is lazilly created by verbose object ctor 52static recorder_t * object_map; 53 54} // anonymous namespace 55 56 57verbose::verbose(char const * name) 58 : 59 set(false) 60{ 61 // all params is treated a part, there is no need to create a 62 // verbose all("all"); it's meaningless. "all" verbose named object is 63 // reserved. 64 if (strcmp(name, "all") == 0) 65 return; 66 if (!object_map) 67 object_map = new recorder_t; 68 object_map->insert(recorder_t::value_type(name, this)); 69} 70 71 72verbose verbose::operator|(verbose const & rhs) 73{ 74 verbose result(*this); 75 result.set = result.set || rhs.set; 76 return result; 77} 78 79 80verbose verbose::operator&(verbose const & rhs) 81{ 82 verbose result(*this); 83 result.set = result.set && rhs.set; 84 return result; 85} 86 87 88bool verbose::setup(string const & name) 89{ 90 if (name == "all") { 91 null_stream.rdbuf(cout.rdbuf()); 92 null_stream.clear(); 93 return true; 94 } 95 if (!object_map) 96 object_map = new recorder_t; 97 pair<recorder_t::iterator, recorder_t::iterator> p_it = 98 object_map->equal_range(name); 99 if (p_it.first == p_it.second) 100 return false; 101 for (; p_it.first != p_it.second; ++p_it.first) 102 p_it.first->second->set = true; 103 return true; 104} 105 106 107bool verbose::setup(vector<string> const & names) 108{ 109 for (size_t i = 0; i < names.size(); ++i) 110 if (!setup(names[i])) 111 return false; 112 return true; 113} 114 115 116ostream& operator<<(cverb_object &, verbose const & v) 117{ 118 return v.set ? cout : null_stream; 119} 120