124 lines
2.5 KiB
C++
124 lines
2.5 KiB
C++
/**
|
|
* @file cverb.cpp
|
|
* verbose output stream
|
|
*
|
|
* @remark Copyright 2002, 2004 OProfile authors
|
|
* @remark Read the file COPYING
|
|
*
|
|
* @author Philippe Elie
|
|
* @author John Levon
|
|
*/
|
|
|
|
#include <cstring>
|
|
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <string>
|
|
#include <cstring>
|
|
|
|
#include "cverb.h"
|
|
|
|
using namespace std;
|
|
|
|
cverb_object cverb;
|
|
verbose vlevel1("level1");
|
|
verbose vdebug("debug");
|
|
verbose vstats("stats");
|
|
verbose vsfile("sfile");
|
|
verbose vxml("xml");
|
|
|
|
namespace {
|
|
|
|
// The right way is to use: ofstream fout; but cverb(fout.rdbuf()) receive
|
|
// a null pointer and stl shipped with 2.91 segfault.
|
|
ofstream fout("/dev/null");
|
|
ostream null_stream(fout.rdbuf());
|
|
|
|
// Used to setup the bad bit in our null stream so output will fail earlier
|
|
// and overhead will be smaller.
|
|
struct setup_stream {
|
|
setup_stream();
|
|
};
|
|
|
|
setup_stream::setup_stream()
|
|
{
|
|
null_stream.clear(ios::badbit);
|
|
}
|
|
|
|
setup_stream setup;
|
|
|
|
// We use a multimap because user can create multiple verbose object with
|
|
// the same name, these are synonymous, setting up one to true will setup
|
|
// all with the same name to true.
|
|
typedef multimap<string, verbose *> recorder_t;
|
|
// The recorder is lazilly created by verbose object ctor
|
|
static recorder_t * object_map;
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
verbose::verbose(char const * name)
|
|
:
|
|
set(false)
|
|
{
|
|
// all params is treated a part, there is no need to create a
|
|
// verbose all("all"); it's meaningless. "all" verbose named object is
|
|
// reserved.
|
|
if (strcmp(name, "all") == 0)
|
|
return;
|
|
if (!object_map)
|
|
object_map = new recorder_t;
|
|
object_map->insert(recorder_t::value_type(name, this));
|
|
}
|
|
|
|
|
|
verbose verbose::operator|(verbose const & rhs)
|
|
{
|
|
verbose result(*this);
|
|
result.set = result.set || rhs.set;
|
|
return result;
|
|
}
|
|
|
|
|
|
verbose verbose::operator&(verbose const & rhs)
|
|
{
|
|
verbose result(*this);
|
|
result.set = result.set && rhs.set;
|
|
return result;
|
|
}
|
|
|
|
|
|
bool verbose::setup(string const & name)
|
|
{
|
|
if (name == "all") {
|
|
null_stream.rdbuf(cout.rdbuf());
|
|
null_stream.clear();
|
|
return true;
|
|
}
|
|
if (!object_map)
|
|
object_map = new recorder_t;
|
|
pair<recorder_t::iterator, recorder_t::iterator> p_it =
|
|
object_map->equal_range(name);
|
|
if (p_it.first == p_it.second)
|
|
return false;
|
|
for (; p_it.first != p_it.second; ++p_it.first)
|
|
p_it.first->second->set = true;
|
|
return true;
|
|
}
|
|
|
|
|
|
bool verbose::setup(vector<string> const & names)
|
|
{
|
|
for (size_t i = 0; i < names.size(); ++i)
|
|
if (!setup(names[i]))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
|
|
ostream& operator<<(cverb_object &, verbose const & v)
|
|
{
|
|
return v.set ? cout : null_stream;
|
|
}
|