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