cverb.cpp

Go to the documentation of this file.
00001 
00012 #include <cstring>
00013 
00014 #include <fstream>
00015 #include <iostream>
00016 #include <map>
00017 #include <string>
00018 #include <cstring>
00019 
00020 #include "cverb.h"
00021 
00022 using namespace std;
00023 
00024 cverb_object cverb;
00025 verbose vlevel1("level1");
00026 verbose vdebug("debug");
00027 verbose vstats("stats");
00028 verbose vsfile("sfile");
00029 verbose varcs("arcs");
00030 verbose vxml("xml");
00031 
00032 namespace {
00033 
00034 // The right way is to use: ofstream fout; but cverb(fout.rdbuf()) receive
00035 // a null pointer and stl shipped with 2.91 segfault.
00036 ofstream fout("/dev/null");
00037 ostream null_stream(fout.rdbuf());
00038 
00039 // Used to setup the bad bit in our null stream so output will fail earlier
00040 // and overhead will be smaller.
00041 struct setup_stream {
00042     setup_stream();
00043 };
00044 
00045 setup_stream::setup_stream()
00046 {
00047     null_stream.clear(ios::badbit);
00048 }
00049 
00050 setup_stream setup;
00051 
00052 // We use a multimap because user can create multiple verbose object with
00053 // the same name, these are synonymous, setting up one to true will setup
00054 // all with the same name to true.
00055 typedef multimap<string, verbose *> recorder_t;
00056 // The recorder is lazilly created by verbose object ctor
00057 static recorder_t * object_map;
00058 
00059 } // anonymous namespace
00060 
00061 
00062 verbose::verbose(char const * name)
00063     :
00064     set(false)
00065 {
00066     // all params is treated a part, there is no need to create a
00067     // verbose all("all"); it's meaningless. "all" verbose named object is
00068     // reserved.
00069     if (strcmp(name, "all") == 0)
00070         return;
00071     if (!object_map)
00072         object_map = new recorder_t;
00073     object_map->insert(recorder_t::value_type(name, this));
00074 }
00075 
00076 
00077 verbose verbose::operator|(verbose const & rhs)
00078 {
00079     verbose result(*this);
00080     result.set = result.set || rhs.set;
00081     return result;
00082 }
00083 
00084 
00085 verbose verbose::operator&(verbose const & rhs)
00086 {
00087     verbose result(*this);
00088     result.set = result.set && rhs.set;
00089     return result;
00090 }
00091 
00092 
00093 bool verbose::setup(string const & name)
00094 {
00095     if (name == "all") {
00096         null_stream.rdbuf(cout.rdbuf());
00097         null_stream.clear();
00098         return true;
00099     }
00100     if (!object_map)
00101         object_map = new recorder_t;
00102     pair<recorder_t::iterator, recorder_t::iterator> p_it =
00103         object_map->equal_range(name);
00104     if (p_it.first == p_it.second)
00105         return false;
00106     for (; p_it.first != p_it.second; ++p_it.first)
00107         p_it.first->second->set = true;
00108     return true;
00109 }
00110 
00111 
00112 bool verbose::setup(vector<string> const & names)
00113 {
00114     for (size_t i = 0; i < names.size(); ++i)
00115         if (!setup(names[i]))
00116             return false;
00117     return true;
00118 }
00119 
00120 
00121 ostream& operator<<(cverb_object &, verbose const & v)
00122 {
00123     return v.set ? cout : null_stream;
00124 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1