18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file cverb.cpp
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * verbose output stream
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2002, 2004  OProfile authors
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <cstring>
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <fstream>
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <iostream>
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <map>
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <string>
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <cstring>
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "cverb.h"
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddusing namespace std;
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddcverb_object cverb;
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddverbose vlevel1("level1");
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddverbose vdebug("debug");
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddverbose vstats("stats");
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddverbose vsfile("sfile");
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddverbose vxml("xml");
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace {
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// The right way is to use: ofstream fout; but cverb(fout.rdbuf()) receive
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// a null pointer and stl shipped with 2.91 segfault.
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddofstream fout("/dev/null");
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddostream null_stream(fout.rdbuf());
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// Used to setup the bad bit in our null stream so output will fail earlier
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// and overhead will be smaller.
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstruct setup_stream {
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	setup_stream();
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsetup_stream::setup_stream()
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	null_stream.clear(ios::badbit);
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsetup_stream setup;
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// We use a multimap because user can create multiple verbose object with
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// the same name, these are synonymous, setting up one to true will setup
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// all with the same name to true.
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtypedef multimap<string, verbose *> recorder_t;
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// The recorder is lazilly created by verbose object ctor
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic recorder_t * object_map;
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} // anonymous namespace
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddverbose::verbose(char const * name)
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	:
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	set(false)
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// all params is treated a part, there is no need to create a
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// verbose all("all"); it's meaningless. "all" verbose named object is
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// reserved.
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (strcmp(name, "all") == 0)
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return;
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!object_map)
718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		object_map = new recorder_t;
728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	object_map->insert(recorder_t::value_type(name, this));
738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddverbose verbose::operator|(verbose const & rhs)
778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	verbose result(*this);
798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	result.set = result.set || rhs.set;
808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return result;
818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddverbose verbose::operator&(verbose const & rhs)
858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	verbose result(*this);
878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	result.set = result.set && rhs.set;
888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return result;
898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool verbose::setup(string const & name)
938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (name == "all") {
958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		null_stream.rdbuf(cout.rdbuf());
968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		null_stream.clear();
978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return true;
988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!object_map)
1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		object_map = new recorder_t;
1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	pair<recorder_t::iterator, recorder_t::iterator> p_it =
1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		object_map->equal_range(name);
1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (p_it.first == p_it.second)
1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return false;
1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (; p_it.first != p_it.second; ++p_it.first)
1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		p_it.first->second->set = true;
1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return true;
1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool verbose::setup(vector<string> const & names)
1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t i = 0; i < names.size(); ++i)
1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (!setup(names[i]))
1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			return false;
1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return true;
1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddostream& operator<<(cverb_object &, verbose const & v)
1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return v.set ? cout : null_stream;
1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
124