What is good practice for generating verbose output? - c++

what is good practice for generating verbose output? currently, i have a function
bool verbose;
int setVerbose(bool v)
{
errormsg = "";
verbose = v;
if (verbose == v)
return 0;
else
return -1;
}
and whenever i want to generate output, i do something like
if (debug)
std::cout << "deleting interp" << std::endl;
however, i don't think that's very elegant. so i wonder what would be a good way to implement this verbosity switch?

The simplest way is to create small class as follows(here is Unicode version, but you can easily change it to single-byte version):
#include <sstream>
#include <boost/format.hpp>
#include <iostream>
using namespace std;
enum log_level_t {
LOG_NOTHING,
LOG_CRITICAL,
LOG_ERROR,
LOG_WARNING,
LOG_INFO,
LOG_DEBUG
};
namespace log_impl {
class formatted_log_t {
public:
formatted_log_t( log_level_t level, const wchar_t* msg ) : fmt(msg), level(level) {}
~formatted_log_t() {
// GLOBAL_LEVEL is a global variable and could be changed at runtime
// Any customization could be here
if ( level <= GLOBAL_LEVEL ) wcout << level << L" " << fmt << endl;
}
template <typename T>
formatted_log_t& operator %(T value) {
fmt % value;
return *this;
}
protected:
log_level_t level;
boost::wformat fmt;
};
}//namespace log_impl
// Helper function. Class formatted_log_t will not be used directly.
template <log_level_t level>
log_impl::formatted_log_t log(const wchar_t* msg) {
return log_impl::formatted_log_t( level, msg );
}
Helper function log was made template to get nice call syntax. Then it could be used in the following way:
int main ()
{
// Log level is clearly separated from the log message
log<LOG_DEBUG>(L"TEST %3% %2% %1%") % 5 % 10 % L"privet";
return 0;
}
You could change verbosity level at runtime by changing global GLOBAL_LEVEL variable.

int threshold = 3;
class mystreambuf: public std::streambuf
{
};
mystreambuf nostreambuf;
std::ostream nocout(&nostreambuf);
#define log(x) ((x >= threshold)? std::cout : nocout)
int main()
{
log(1) << "No hello?" << std::endl; // Not printed on console, too low log level.
log(5) << "Hello world!" << std::endl; // Will print.
return 0;
}

You could use log4cpp

You can wrap your functionality in a class that supports the << operator which allows you to do something like
class Trace {
public:
enum { Enable, Disable } state;
// ...
operator<<(...)
};
Then you can do something like
trace << Trace::Enable;
trace << "deleting interp"

1. If you are using g++ you could use the -D flag, this allows the compilator to define a macro of your choice.
Defining the
For instance :
#ifdef DEBUG_FLAG
printf("My error message");
#endif
2. I agree this isn't elegant either, so to make it a bit nicer :
void verbose(const char * fmt, ... )
{
va_list args; /* Used as a pointer to the next variable argument. */
va_start( args, fmt ); /* Initialize the pointer to arguments. */
#ifdef DEBUG_FLAG
printf(fmt, &args);
#endif
/*This isn't tested, the point is to be able to pass args to
printf*/
}
That you could use like printf :
verbose("Error number %d\n",errorno);
3. A third solution easier, and more C++ and Unix like is to pass an argument to your program that is going to be used - as the macro earlier - to initialize a particular variable (that could be a global const).
Example :
$ ./myprogram -v
if(optarg('v')) static const verbose = 1;

Related

Is there a way to read the function parameter as the exact name passed in c++?

For my program (C++), I need to read one of the function parameter as it is given while calling the function, for example:
void foo(int arg)
{
// I need to read the "arg" parameter here, not its value but the exact thing passed while calling the "foo" function
}
for example:
int bar = 10;
foo(bar); // I want to read "bar" string
Is there a way to do that?
One of the alternate option I can see is make two parameters and call the function like:
foo(bar, "bar");
I'm a beginner in c++, so it may be a silly question...
AS there is no build-in reflection in C++, in resulting code all ids will be gone. But you can emulate it by using stringize operator #, if you don't mind to use some wrappers. assert() macro in some implementations makes use of it.
#include <iostream>
void order(int arg1, int arg2, const char* str)
{
std::cout << str << arg1*arg2 << std::endl;
}
#define REFLECT_INVOKE(func, ...) (func)(__VA_ARGS__, #func "(" #__VA_ARGS__ ") = ")
int main()
{
int x = 6;
int y = 11;
REFLECT_INVOKE(order,x,y);
}
Output:
order(x,y) = 66
Operator # literally wraps following token in quotes before placing result into processed source before compilation, so statement REFLECT_INVOKE(order,x,y); is processed into (order)(x,y,"order" "(" "x,y" ") = ");
We can make it a bit more universal, using new features (there is probably simple and obvious way to do this):
int order(int arg1, int arg2)
{
return arg1*arg2;
}
template<class F, class ...Args>
auto debug_call( F func, const char* str, Args... args) ->
decltype(std::forward<F>(func)(std::forward<Args>(args)...))
{
if constexpr ( std::is_same<decltype(std::forward<F>(func)(std::forward<Args>(args)...)),void>::value) {
std::cout << str;
func(args...);
} else {
auto res = func(args...);
std::cout << str << "= " << res;
return res;
}
}
#define REFLECT_INVOKE(func, ...) (debug_call)(func, #func "(" #__VA_ARGS__ ") ", __VA_ARGS__)
int main()
{
int x = 6;
int y = 11;
REFLECT_INVOKE(order,x,y);
}
This is barely usable outside of debugging purposes.

std::clog wrapper with color and header fails to print integers properly

I need a class to wrap calls to std::clog so that:
Each message is prefixed by a header that includes time and the name of the entity that generated the message.
Messages are coloured in accordance to error types (e.g. debug, warning, error).
The way to use it is exactly equivalent to std::clog << "..." for all its features (i.e. the ability to have implicit basic type-to-string conversions, stream manipulators, flushing, etc.)
My attempt has been based on many examples found in this forum (*), but I guess in a kind of a wrong way, because my class is a bit faulty.
Essentially what I tried is to extend std::streambuf by overriding the overflow and xputn methods in a way that they end up calling clog's operator<<.
NB: I found it difficult to keep my question complete(**), minimal and verifiable all at the same time, so any suggestions/comments on that will be much appreciated. What matters most to me, though, is the approach I have taken rather than the specific bugs or implementation flaws.
class LogStream : public std::streambuf
{
public:
enum class Color { RED_BRIGHT, RED_DARK, /* ...others */ NO_COLOR };
LogStream(void);
LogStream(std::basic_ostream<char>& out, std::string cname, char c, Color icon_color, Color text_color = Color::NO_COLOR);
/* Non-copiable. */
LogStream(const LogStream&) = delete;
LogStream& operator=(const LogStream&) = delete;
static void setNameLength(int l);
protected:
int_type overflow(int_type c = traits_type::eof());
std::streamsize xsputn(const char* s, std::streamsize n);
private:
/* Important stuff: */
std::basic_ostream<char>& m_out;
bool m_new_line;
void conditionalPrintHeader(void);
void endLine(void);
/* For message decoration purposes: */
Color m_color_icon;
Color m_color_text;
char m_icon;
std::string m_cname;
static std::map<Color, const std::string> m_color_lut;
};
/* A macro to create static instances of a logger later in each CPP file. */
#define CREATE_LOGGER(klass) \
namespace Log { \
static std::ostream dbg(new LogStream( \
std::clog, \
#klass, \
'>', \
LogStream::Color::RED_BRIGHT, \
LogStream::Color::NO_COLOR)); \
static std::ostream err(new LogStream( \
std::clog, \
#klass, \
'e', \
LogStream::Color::RED_BRIGHT, \
LogStream::Color::RED_DARK)); \
}
My overridden functions are implemented like so:
std::streamsize LogStream::xsputn(const char* s, std::streamsize n)
{
conditionalPrintHeader();
if(s[n - 1] == '\n') {
m_new_line = true;
endLine();
}
m_out << s;
return n;
}
LogStream::int_type LogStream::overflow(int_type c)
{
if(c == traits_type::eof()) {
return traits_type::eof();
} else {
char_type ch = traits_type::to_char_type(c);
return xsputn(&ch, 1) == 1 ? c : traits_type::eof();
}
}
void LogStream::conditionalPrintHeader(void)
{
if(m_new_line) {
m_out << "... header and color escape codes ...";
m_new_line = false;
}
}
void LogStream::endLine(void)
{
m_out << "color escape code for no color.";
}
The functions conditionalPrintHeader and endLine essentially try to implement this basic structure:
[header string] [ANSI color code] [<the log message>] [end color code]
So that when I do:
Log::warn << "Integer: " << 123 << ", Bool: " << std::boolalpha << true << ", Float: " << 3.1415f << "\n";
The terminal outputs:
HEADER + [START COLOR] Integer: 123, Bool: true, Float: 3.1415 [END COLOR]
Most of the time everything works great except when I need to print integer values. Instead of the number, I get additional garbage, like so:
[ ... ] Integer: 123�~c, Bool: true, Float: 3.1415
Notes:
(*) Similar questions that inspired or directly contributed to my solution:
https://stackoverflow.com/a/10921803/1876268 --Where I took most of the implementation concept.
Add time stamp with std::cout
Correct way to declare/define custom cout-like object
https://codereview.stackexchange.com/a/187373/176115
Correct implementation of std::streambuf::overflow
(**) I pasted the whole header and source files in order to be as complete as possible and in case I'm missing the error somewhere else: Log.hpp, Log.cpp.
For now I considered that the problem laid in the character string argument of xsputn (which I assumed is not null-terminated). I solved my issue with integers like as follows, but I'm still unclear whether the approach is good or not.
std::streamsize LogStream::xsputn(const char* s, std::streamsize n)
{
conditionalPrintHeader();
if(s[n - 1] == '\n') {
m_new_line = true;
endLine();
}
std::string str;
for(int c = 0; c < n; c++) {
str += s[c];
}
m_out << str;
return n;
}

Expanding macro within macro

In the following example I expect to see
doSomething
asserting in "doSomething()"
However i dont see any output on console.
When I use HUTAssert(doSomething()) in main() , I see the expected output, so I expect this has to do with expending a macro within another macro
#include <iostream>
using namespace std;
#define LOPTAssertEnabled 1
#define HUTAssert(expr) ( (expr)? (void(0)) : assertMe(#expr) )
#define HAOPAssert(expr) ((isLOPTAssertEnabled())? HUTAssert(#expr) : void(expr))
void assertMe(char const* expr) {
std::cout <<" asserting in "<<expr;
}
bool doSomething() {
std::cout <<" did something "<<std::endl;
return false;
}
bool isLOPTAssertEnabled() {
return LOPTAssertEnabled;
}
int main() {
HAOPAssert(doSomething());
}
You can easily see what preprocessor is doing. For example, with gcc (g++) you can use the "-E" option to see what preprocessor is producing. In your case, you are getting this:
void assertMe(char const* expr) {
std::cout <<" asserting in "<<expr;
}
bool doSomething() {
std::cout <<" did something "<<std::endl;
return false;
}
bool isLOPTAssertEnabled() {
return 1;
}
int main() {
((isLOPTAssertEnabled())? ( ("doSomething()")? (void(0)) :
assertMe("\"doSomething()\"") ) : void(doSomething()));
}
I believe, this is not what your are expecting. However, if you strip off #, which is "stringfying" your token, from HUTAssert(#expr), I believe it will be close to what you are expecting

Correct way of unpacking operation type from network application

I come from python world, and as a weekend project I decided to write a simple UDP server in c++. I have a question regarding correct way of discovering the type of incoming request. My approach is to have a class for every possible type of request. Upon packet arrival I have to unpack it's OPID (operation id) and instantiate correct class. To do that I have to bind OPIDs with the classes, and the only way I'm familiar of doing this in c++ involves huge switch:case block. Doing this doesn't really feels right for me, also If I understand UncleBob correctly, this goes against few OOP practices. As code describes the best one's intentions, here's python equivalent of what I'm trying to do with c++.
class BaseOperation:
OPID = 0
def process(packet_data):
raise NotImplementedError("blah blah")
class FooOperation(BaseOperation):
OPID = 1
def process(packet_data):
print("Foo on the packet!")
class BarOperation(BaseOperation):
OPID = 2
def process(packet_data):
print("Bar on the packet!")
opid_mappings = {
FooOperation.OPID: FooOperation,
BarOperation.OPID: BarOperation
}
Somewhere in code handling the incoming packet
def handle_connection(packet):
try:
operation = opid_mappings[get_opid(packet)]()
except KeyError:
print("Unknown OPID")
return
operation.process(get_data(packet))
Really quick hack of object-based solution. This might not be the right way to go in our wonderful new C++11 world of std::function.
If the children of BaseOperation need to store state, go objects!
#include <iostream>
#include <map>
class BaseOperation
{
protected:
int OPID;
public:
virtual ~BaseOperation()
{
}
virtual int operator()() = 0;
};
class FooOperation:public BaseOperation
{
public:
static constexpr int OPID = 1;
FooOperation()
{
}
int operator()()
{
// do parsing
return OPID; // just for convenience so we can tell who was called
}
};
constexpr int FooOperation::OPID; // allocate storage for static
class BarOperation:public BaseOperation
{
public:
static constexpr int OPID = 2;
BarOperation()
{
}
int operator()()
{
// do parsing
return OPID; // just for convenience so we can tell who was called
}
};
constexpr int BarOperation::OPID; // allocate storage for static
std::map<int, BaseOperation*> opid_mappings{
{FooOperation::OPID, new FooOperation()},
{BarOperation::OPID, new BarOperation()}
};
int main()
{
std::cout << "calling OPID 1:" << (*opid_mappings[1])() << std::endl;
std::cout << "calling OPID 2:" << (*opid_mappings[2])() << std::endl;
for (std::pair<int, BaseOperation*> todel: opid_mappings)
{
delete todel.second;
}
return 0;
}
This also ignores the fact that there is probably no need for the map. If the OPIDs are sequential, a good ol' dumb array solves the problem. I like the map because it won't screw up if someone moves a parser handler or inserts one into the middle of the list.
Regardless, this has a bunch of memory management problems, such as the need for the for loop deleting the parser objects at the bottom of main. This could be solved with std::unique_ptr, but this is probably a rabbit hole we don't need to go down.
Odds are really good that the parser doesn't have any state and we can just use a map of OPIDs and std::function.
#include <iostream>
#include <map>
#include <functional>
static constexpr int FooOPID = 1;
int fooOperation()
{
// do parsing
return FooOPID;
}
static constexpr int BarOPID = 2;
int BarOperation()
{
// do parsing
return BarOPID;
}
std::map<int, std::function<int()>> opid_mappings {
{FooOPID, fooOperation},
{BarOPID, BarOperation}
};
int main()
{
std::cout << "calling OPID 1:" << opid_mappings[1]() << std::endl;
std::cout << "calling OPID 2:" << opid_mappings[2]() << std::endl;
return 0;
}
And because the parser's are kind of useless if you aren't passing anything in, one last tweak:
#include <iostream>
#include <map>
#include <functional>
struct Packet
{
//whatever you need here. Probably a buffer reference and a length
};
static constexpr int FooOPID = 1;
int fooOperation(Packet & packet)
{
// do parsing
return FooOPID;
}
static constexpr int BarOPID = 2;
int BarOperation(Packet & packet)
{
// do parsing
return BarOPID;
}
std::map<int, std::function<int(Packet &)>> opid_mappings {
{FooOPID, fooOperation},
{BarOPID, BarOperation}
};
int main()
{
Packet packet;
std::cout << "calling OPID 1:" << opid_mappings[1](packet) << std::endl;
std::cout << "calling OPID 2:" << opid_mappings[2](packet) << std::endl;
return 0;
}

Calling function during runtime based on function name match

Apologies in advance the possibly vague Title, best I could come up with.
I have the following C++ and text file:
cpp file:
class Test
{
int var1;
int var2;
public:
bool set_var1();
bool set_var1();
bool set(string var_name);
void process_file();
}
text file:
var1 value1
var2 value2
Objective - In process_file(), read/parse the text file, and for each varX in file call the corresponding set_varX().
One option, in function set(), compare var_name to "var1" / "var2" / etc, and
call corresponding set_varX(). The issue I have with this approach, as more
lines are added to the text file, the code becomes...ugly, with the long "if-else"
code block in set().
Another option, create a static map
"var1" set_var1()
"var2" set_var2()
set() will iterate over the map, and upon a string compare match call the corresponding func_ptr. This option requires maintaining a map structure.
Though I prefer the second option, less code changes as the test file increases, is there another option. Just thinking out loud, in set(), can I take the string var_name, and prepend set_, and call set_var_name(), basically somehow avoid the string compare, which is done in both the cases above. My gut feeling, in C++, that is not possible to do during runtime
Thank you,
Ahmed.
It sounds like you're asking about reflection, which is not a feature of C++, so this won't be possible. As you pointed out there are solutions to the problem, but all of them will involve a mapping of string names to functions, and you'll have to construct/maintain that mapping yourself. The language won't do this for you.
You can improve option 2 by making var1, var2.. self registering types. New keywords cause no code changes, only new types. Therefor the map has to be some kind of global object, singleton etc.
A very simple example:
struct Setter
{
virtual ~Setter() = default;
virtual void Process(std::string content) const = 0;
};
class SetterMap
{
public:
bool RegisterSetter(std::string keyword, std::unique_ptr<Setter> setter) {
setters[keyword] = move(setter);
return true;
}
const Setter& GetSetter(const std::string& keyword) const {
return *(setters.at(keyword));
}
private:
std::map<std::string, std::unique_ptr<Setter>> setters;
};
inline SetterMap& GetSetterMap() {
static SetterMap map;
return map;
}
Define and register some setters:
struct Var1 : Setter {
void Process(std::string content) const override {
}
};
namespace {
bool var1registered = GetSetterMap().RegisterSetter(
"var1", std::make_unique<Var1>());
}
struct Var2 : Setter {
void Process(std::string content) const override {
}
};
namespace {
bool var2registered = GetSetterMap().RegisterSetter(
"var2", std::make_unique<Var2>());
}
Use the setter map:
int main()
{
std::string line = "var1: blablab";
GetSetterMap().GetSetter("var1").Process(line);
}
Depending on your needs, you might consider embedding Lua and changing the syntax of the text file to something like:
test.var1 = 1234
test.var2 = 42
Here, test would be a global Lua table that you instantiate from the C++ side and assign a metatable to using lua_setmetatable(). The metatable would have a __newindex method as described here. If you're familiar with Python, this is sort of like providing a __setattr__ metamethod—i.e., it intercepts assignment of non-existent fields and executes some user-specified magic.
The 'trick' in your case is to create a metatable in Lua that re-routes access to the var1, var2, etc. fields of test to a lua_CFunction wrapper that sets the corresponding field on the underlying Test object. After that, you can simply 'run' the file using luaL_dofile().
A quick-n-dirty example (tested against Lua 5.1.5) that illustrates the gist of the idea is appended below. (It needs to be compiled with -std=c++11 due to the use of a raw string literal.)
This approach is certainly overkill if your needs are very specific/targeted. However, if you want/need scripting in your app, anyway, embedding Lua is a great solution.
NOTE: It is not strictly required to use a separate table (e.g., test in the example). Lua stores global variables in a table named _G, so you could instead set a metatable for _G. However, doing so is a bit of a hack; it makes the example harder to follow, and would limit some of the other ways you can use Lua in your host application.
#include <cassert>
#include <iostream>
#include <string>
#include <cstdlib>
#include <lua.hpp>
static const char* regkey = "Test";
class Test
{
public:
Test();
virtual ~Test();
void set_var1(int value);
void set_var2(int value);
void process_file(std::string const& filepath);
private:
int var1, var2;
lua_State* L_;
};
static int set_var(lua_State* L)
{
// Get the table, key and value
std::string key = lua_tostring(L, 1);
int value = lua_tointeger(L, 2);
// Get the Test instance pointer from the Lua registry
lua_pushlightuserdata(L, (void*)regkey);
lua_gettable(L, LUA_REGISTRYINDEX);
Test* test = (Test*) lua_touserdata(L, -1);
// Execute set_XXX() as appropriate
if (test == NULL) {
std::cerr << "Pointer in registry is missing or NULL, aborting..."
<< std::endl;
exit(EXIT_FAILURE);
}
if (key == "var1") {
test->set_var1(value);
}
else if (key == "var2") {
test->set_var2(value);
}
else {
std::string errmsg = "No such variable '" + key + "'";
lua_pushstring(L, errmsg.c_str());
lua_error(L);
}
return 0;
}
Test::Test()
{
L_ = luaL_newstate();
assert(L_);
luaL_openlibs(L_);
// Point the Lua global '_set_var' at our C set_var() function
lua_pushcfunction(L_, &set_var);
lua_setglobal(L_, "_set_var");
// Store our `this' pointer in the Lua registry
lua_pushlightuserdata(L_, (void*)regkey);
lua_pushlightuserdata(L_, this);
lua_settable(L_, LUA_REGISTRYINDEX);
// Set up the metatable to re-route "foo = X" to "_set_var('foo', X)"
std::string script = R"SCRIPT(
test = {}
local mt = {}
mt.__newindex = function(tbl, key, value)
_set_var(key, value)
end
setmetatable(test, mt)
)SCRIPT";
int retval = luaL_dostring(L_, script.c_str());
if (retval != 0) {
std::cerr << "luaL_dostring() failed (\""
<< lua_tostring(L_, -1)
<< "\"), aborting..."
<< std::endl;
exit(EXIT_FAILURE);
}
}
Test::~Test()
{
lua_close(L_);
}
void Test::set_var1(int value)
{
std::cout << "Setting var1 to " << value << std::endl;
var1 = value;
}
void Test::set_var2(int value)
{
std::cout << "Setting var2 to " << value << std::endl;
var2 = value;
}
void Test::process_file(std::string const& filepath)
{
int retval = luaL_dofile(L_, filepath.c_str());
if (retval != 0) {
std::cerr << "luaL_dofile() failed (\""
<< lua_tostring(L_, -1)
<< "\"), aborting..."
<< std::endl;
exit(EXIT_FAILURE);
}
}
int main()
{
Test().process_file("config.ini");
return 0;
}