How to overload printf or cout - c++

I use cout statements in my program for debugging purposes. I would like to make a function that works like it, or works like printf, but is sensitive to a global variable. If this global variable is true, then it will print to screen. If it is false, then it won't print anything. Is there already a function like this? If not, then how can it be made?

Something like this:
int myPrintf(const char* format, ...)
{
if (globalCheck == 0)
return 0
va_list vl;
va_start(vl, format);
auto ret = vprintf(format, vl);
va_end(vl);
return ret;
}
va_start and va_end take the arguments in the ... and encapsulate them in a va_list. with this va_list you can then the vprintf which is a variant of printf designed exactly for this need.
Side note - usually it is bad practice to use global variables. A better thing to do is to encapsulate it in a class like this -
class ConditionalPrinter {
public:
ConditionalPrinter() : m_enable(true) {}
void setOut(bool enable) { m_enable = enable; }
int myPrintf(const char* format, ...);
private:
bool m_enable;
}
and then to check m_enable instead of the global variable.
Usage of this looks like this:
ConditionalPrinter p;
p.myPrintf("hello %d", 1); // printed
p.setOut(false);
p.myPrintf("hello2 %d", 1); // not printed
....

Don't write it yourself. Doing it right is much harder then you think. Even harder when you need threads and efficiency. Use one of existing logging libraries like:
glog: http://code.google.com/p/google-glog/ (I prefer this - it is lightweight and do what it needs to do)
Log4cpp http://log4cpp.sourceforge.net/ (powerful and configuration compatible with popular java logging)
... add your favorite to this wiki

As someone else said, there are several good logging frameworks available. However, if you want to roll your own, the first thing to note is that cout isn't a function, it's a stream. The function is operator<<. What you can do is something like the following:
/* trace.h */
extern ostream debug;
void trace_init();
void trace_done();
/* trace.cpp */
#include "trace.h"
ostream debug(cout.rdbuf());
static ofstream null;
void trace_init()
{
null.open("/dev/null");
if(output_is_disabled) { // put whatever your condition is here
debug.rdbuf(null.rdbuf());
}
}
void trace_done()
{
null.close();
}
You might have to adjust a bit if you're on a platform without /dev/null. What this does is let you write
debug << "here's some output << endl;
and if you have the output enabled, it will write to cout. If not, it will write to /dev/null where you won't see anything.
For that matter, you could just set cout's rdbuf to somewhere where you won't see that output, but I would find that to be a really bad idea. Creating new streams gives you a lot more flexibility in controlling your output.

Related

Creating a custom printf with validation and syntax highlighting

I'd like to be able to create a logging mechanism, which very simply passes arguments through to printf, but I need syntax highlighting, and validation of input. This is the outline for the Log namespace I have so far.
#pragma once
#include "pch.h"
namespace Log
{
// Determines whether to create the console window or not.
// Turn off for before release.
extern bool CreateConsoleWindow;
// Initialisation.
extern bool Init();
// Writes a line to the console, appended with \r\n.
extern void WriteLine(const char* _Format, ...);
// Writes a line to the console, with a [Debug] prepend.
extern void DebugInfo(const char* _Format, ...);
// Writes a line to the console, with a [Server] prepend.
extern void ServerInfo(const char* _Format, ...);
// Destruction.
extern bool Dispose();
}
This is my implementation for Log::WriteLine(_Format, ...):
// Writes a line to the console, appended with \r\n.
void WriteLine(const char* _Format, ...)
{
// Print the message.
char buffer[4096];
va_list args;
va_start(args, _Format);
auto rc = vsnprintf(buffer, sizeof(buffer), _Format, args);
va_end(args);
// Append the new line.
printf("\r\n");
}
But when I do this, I lose all the validation and syntax highlighting, which is essential, being a beginner, from the input string. For instance:
auto hash = Crypto::GetHash(syntax[1].c_str()); // unsigned long, by way of multiple nested macros.
printf("Hash: %d", hash);
This would show %d in lime green, and there would be a warning on hash in the the printf, saying it won't be displayed, because it expects %lu. I rely on VS to teach me what I'm doing wrong, so that I can learn from my mistakes.
If I do the same with my function:
auto hash = Crypto::GetHash(syntax[1].c_str()); // unsigned long, by way of multiple nested macros.
Log::WriteLine("Hash: %d", hash);
Then %d is the same brown as the rest of the string, and there is no validation error.
These two things are essential. Is there any way to make this work properly? I'm new to C++ after about a decade of .NET experience, and the learning curve is massive. I thought I'd start with the basics, just an easy logging system, so I can see what is being output at any time, in a clean and elegant way. In C#, this would have only taken a couple of minutes to put together, but in C++, it's now four hours later, I have about 40 tabs open in three windows of Firefox, and I'm still smashing my head against every brick wall it's possible to come across.
I've tried to define a macro inside the namespace:
#define WriteLine(_Format, ...) printf(_Format, __VA_ARGS__)
But is says it can't find printf. I've tried decorating with _Printf_format_string_:
extern int _cdecl DebugInfo(_Printf_format_string_ const char* _Format, ...);
But that makes no difference. I've tried __attribute__((format(printf, 1, 2)))
extern void WriteLine(const char* _Format, ...) __attribute__((format(printf, 1, 2)));
But that throws up a mass of errors about expecting a {, unexpected identifier, and expected a declaration, but doesn't say where, or why, or how.
Am I asking too much of C++, for such a basic request?
Modern code editors and IDEs (and compilers!) provide additional support for the printf family of functions beyond the scope of the C++ and C languages. One prime example of that is extended error checking for the format strings, which cannot be done in C at all, and in C++ only with major pains. There are a few ways of achieving your aim with only minor modifications.
<iostreams> Solution
By default, std::cout is synchronized with printf, so you may not actually need to deal with printf directly. There are many solutions out there for how to achieve various results with the iostreams library framework, even though it is a bit of a hassle to use. It is type-safe, thus not requiring additional IDE support to directly show mistakes.
Note that iostreams has a rather bad reputation for its complexity and ease-of-use.
Typesafe Variadic Template
You can use a variadic template along the lines of:
void add_format_specifier(std::ostream& out, int const&) {
out << "%d";
}
void add_format_specifier(std::ostream& out, char const*) {
out << "%s";
}
void add_format_specifier(std::ostream& out, hex const&) {
out << "%x";
}
template<typename... Args>
void WriteLine(Args&&... args) {
std::ostringstream format;
((void)0, ..., add_format_specifier(format, args));
printf(format.str().c_str(), args...);
}
This solution is type-safe and compiler-checked, again without relying on special-casing printf. Personally, I would suggest going down this route, as it combines maximum flexibility with easy type-checking - and does away with the format specifier ;). You may wish to decide whether using printf as the low-level primitive is really what you want to do here, but it is easily exchanged for other methods of output.
Compile-Time Checking of a Format String
It is possible to add custom compile-time checking of format specifiers that you can then static_assert. The basic building blocks that you need is a variadic template that also takes your format specifier (basically, you need to preserve types inside your variadic function), and which calls a format specifier along the lines of:
template<std::size_t N>
consteval bool check_format(char const (&format)[N], std::size_t i) {
for(; i < N; ++i) {
if(format[i] == '%') {
if(i + 1 >= N) {
return false;
}
if(format[i + 1] == '%') {
++i; // skip literal '%'
} else {
return false; // no more specifiers expected
}
}
}
return true;
}
template<std::size_t N, typename T, typename... Args>
consteval bool check_format(char const (&format)[N], std::size_t i) {
for(; i < N; ++i) {
if(format[i] == '%') {
if(i + 1 >= N) {
return false; // unterminated format specifier
}
if(format[i + 1] == '%') {
++i; // skip literal '%'
} else {
if constexpr(std::is_same_v<T, int>) {
// quickly check if it is an acceptable integer format specifier
if(format[i + 1] != 'd' && format[i + 1] != 'x') {
return false;
} else {
return check_format<N, Args...>(format, i + 2);
}
} else {
return false; // unknown format specifier
}
}
}
}
return false;
}
See here for a bit more context. (Note: This example relies on the C++20 consteval specifier, which may not be supported by your compiler. Similar effects can be achieved with constexpr.)
This solution will give you compile-time errors, but no syntax highlighting - C++ cannot impact how your IDE draws strings (yet ;) ).
Macro Solution
While your macro #define WriteLine(_Format, ...) printf(_Format, __VA_ARGS__) does not really allow you to do all that much with respect to implementing anything beyond renaming printf, it will work, provided that the user code also include <cstdio>. If you provide a header with that macro, you may wish to just add the inclusion in there for ease of use.
There is only a tiny improvement to be made, so that the macro also works for calls of the form WriteLine("abc"):
#include <cstdio>
#define WriteLine(_Format, ...) printf(_Format __VA_OPT__(,) __VA_ARGS__)

clang-format Function and error check in the same line

I struggle to set up clang-format to allow short lines for such format,
ierr = fun(); CHKERRQ(ierr);
clang-format break the line, as result
ierr = fun();
CHKERRQ(ierr);
It is a solution to stop clang-fromat to break short lines? Or this is in principle wrong idea to format code like this. Any advice very appreciated.
EDIT: Following Guillaume answer
In fact, I have a slightly more complex problem, where errors codes of different types are returned by two libraries, in particular, PETSc and MoAB. Also, this system has own error codes, which need to be handled. All without compromising efficiency.
struct ErrorCheckerCode {
inline void operator<<(const MoFEMErrorCode err) {
if (PetscUnlikely(err)) {
// Handle & thorw PETSc/MoFEM error
}
return;
}
inline void
operator<<(const moab::ErrorCode err) {
if (PetscLikely(MB_SUCCESS != err)) {
// Handle & trow MOAB error
}
return;
}
static const char *fUNC;
static const char *fILE;
static int lINE;
};
struct ErrorCheckerFunction {
inline ErrorCheckerCode operator<<(const char *func) {
ErrorCheckerCode::fUNC = func;
return ErrorCheckerCode();
}
};
struct ErrorCheckerFile {
inline ErrorCheckerFunction operator<<(const char *file) {
ErrorCheckerCode::fILE = file;
return ErrorCheckerFunction();
}
};
struct ErrorCheckerLine {
inline ErrorCheckerFile operator<<(int line) {
ErrorCheckerCode::lINE = line;
return ErrorCheckerFile();
}
};
And definition follows this:
#define CHKERR \
ErrorCheckerLine() << __LINE__ << __FILE__ << PETSC_FUNCTION_NAME <<
So at the end I can handle errors like this
CHKERR fun_moab();
CHKERR fun_petsc();
CHKERR fun_mofem();
This implementation is essential, so it has to be done optimally, I wonder if that can be done in simpler, more efficient way. Criticism or advice is very welcome.
Note:
As a commend. It is funny how formatting of code triggers this type of developments.
I use clang-format a lot and I don't think it can achieve this kind of formatting.
I've encountered this pattern a lot in libraries using OpenGL and DirectX. You have a API with error codes or an error stack like in OpenGL and every function might fail or issue a warning. You want your code to be optimized in release and still have a debug mode to find preciselly where things went wrong in case you spot a bug.
Some libraries provide some kind of error callback that you can set and will effectively be called each time there is a relevent error.
In case you want something more customized or no error callback is provided, you can write a simple wrapper that does a systematic error checking and warnings logging.
With these solutions you can even implement some mechanism to activate the debugging at runtime.
Now, if you are writing the library or functions that return errors returned this way, you might want to include the debug mode directly in the library with the debug callback strategy.
Now, if you want to stick to the macro solution, you could do the following:
struct ErrorChecker
{
ErrorChecker& operator << (int ierr)
{
// Error checking code
return *this;
}
};
#define CHKERR ErrorChecker() <<
and then
CHKERR fun();

Best practice for creating silent CLI option?

I have a program that writes occasional status updates, but I'm sure some will want it to run silently so I have provided a -s / --silent CLI option. What would be the best way to have my program abide by that parameter?
This method adds a global variable, and still executes the fprintf functions adding to the smell slightly.
FILE *outfile
if (silent) {
*outfile = NULL;}
else {
*outfile = stderr;}
fprintf (outfile, "This program can run silently");
This method also adds a global variable, and if statments littered throughout the code also adding to the smell.
if (!(silent)){
fprintf (stdout, "This program can run silently");
}
Ternary operators with a global variable might be more elegant:
(silent) ? : fprintf(stdout, "This program can run silently");
Are there better practices than any of these methods? Are there shortcomings to any one that I'm not seeing?
As Don Shankin said in his comment, the most maintainable way to do it is by wrapping fprintf() in a function that implements your filtering logic, and then have your code call the wrapper function rather than calling fprintf() directly. That way you only have to implement the filtering logic in a single location and not all over the place. Here's a program that demonstrates the technique:
#include <stdio.h>
#include <stdarg.h>
bool silent = false;
void my_fprintf(FILE * outFile, const char * fmt, ...)
{
if (silent == false)
{
va_list argsList;
va_start(argsList, fmt);
vfprintf(outFile, fmt, argsList);
va_end(argsList);
}
}
int main(int argc, char ** argv)
{
my_fprintf(stdout, "Not silent now...\n");
silent = true;
my_fprintf(stdout, "But now I'm silent, so you won't see this!\n");
silent = false;
my_fprintf(stdout, "Silent is false again!\n");
return 0;
}
... and here is the output from the program:
Not silent now...
Silent is false again!
Since it's also tagged C++, I'd like to point out that you can replace the output buffer of std::cout by calling std::cout.rdbuf(newbuf). A "devnull buff" is trivial to implement.

Prepending a string to a logger on function entrance

I have a logger class. Call it MyLogger. I may use it in a function like this:
void MyFunc(MyLogger& oLogger)
{
//Do stuff
oLogger.Log("In MyFunc : Some Error");
//Do something else
oLogger.Log("In MyFunc : Some other error");
}
Now, I want to prepend "In MyFunc" to the logs if the log comes from inside MyFunc. Similarly for other functions...
Because this is tiresome, I tried something like this:
void MyLogger::PushPrependString(const char*)
{
//Store prepend string in stack and set it as current prepend string.
}
void MyLogger::PopPrependString()
{
//Pop the most recent prepend string.
}
Now, I can use these two functions like this:
void MyFunc(MyLogger& oLogger)
{
oLogger.PushPrependString("In MyFunc : ");
//Do stuff
oLogger.Log("Some Error");
//Do something else
oLogger.Log("Some other error");
oLogger.PopPrependString();
}
The trouble is, if there are multiple returns in a function, this becomes ugly. Is there any way around this? Is this a common problem? Is there any preprocessor macro like __FILE__ or __LINE__ for getting the name of the function a line appears in? Any comments would be appreciated. Thanks.
"The trouble is, if there are multiple returns in a function, this becomes ugly. Is there any way around this?"
Yes, just use an object with constructor (calls PushPrependString) and destructor (calls PopPrependString).
class LogPrefix
{
private:
MyLogger* logger_;
LogPrefix( LogPrefix const& ); // No such.
LogPrefix& operator=( LogPrefix const& ); // No such.
public:
LogPrefix( MyLogger& logger, char const s[] )
: logger_( &logger )
{
logger_->PushPrependString( s );
}
~LogPrefix()
{
logger_->PopPrependString();
}
};
Disclaimer: off the cuff code, not touched by compiler's hands...
"Is this a common problem?"
Yes.
"Is there any preprocessor macro like FILE or LINE for getting the name of the function a line appears in?"
Not in C++98. Various compilers offer various extensions that do that. IIRC C++0x adopts the C99 scheme, which unfortunately just provides static strings.
Cheers & hth.
RAII - Resource Acquisition Is Initialization.
In this case, you create an object on entry to the function that identifies the current function to the logging system; when the function exits (by any return or by exception thrown or by exception not caught), the object will be destroyed, and the destructor changes what is printed in future by the logging system.
In C99, and maybe in some C++ compilers such as G++, there is a predefined variable, __func__ containing the function name. The C++ equivalent is more complex, I believe.

Is it possible to *safely* return a TCHAR* from a function?

I've created a function that will convert all the event notification codes to strings. Pretty simple stuff really.
I've got a bunch of consts like
const _bstr_t DIRECTSHOW_MSG_EC_ACTIVATE("A video window is being activated or deactivated.");
const _bstr_t DIRECTSHOW_MSG_EC_BUFFERING_DATA("The graph is buffering data, or has stopped buffering data.");
const _bstr_t DIRECTSHOW_MSG_EC_BUILT("Send by the Video Control when a graph has been built. Not forwarded to applications.");
.... etc....
and my function
TCHAR* GetDirectShowMessageDisplayText( int messageNumber )
{
switch( messageNumber )
{
case EC_ACTIVATE: return DIRECTSHOW_MSG_EC_ACTIVATE;
case EC_BUFFERING_DATA: return DIRECTSHOW_MSG_EC_BUFFERING_DATA;
case EC_BUILT: return DIRECTSHOW_MSG_EC_BUILT;
... etc ...
No big deal. Took me 5 minutes to throw together.
... but I simply don't trust that I've got all the possible values, so I want to have a default to return something like "Unexpected notification code (7410)" if no matches are found.
Unfortunately, I can't think of anyway to return a valid pointer, without forcing the caller to delete the string's memory ... which is not only nasty, but also conflicts with the simplicity of the other return values.
So I can't think of any way to do this without changing the return value to a parameter where the user passes in a buffer and a string length. Which would make my function look like
BOOL GetDirectShowMessageDisplayText( int messageNumber, TCHAR* outBuffer, int bufferLength )
{
... etc ...
I really don't want to do that. There must be a better way.
Is there?
I'm coming back to C++ after a 10 year hiatus, so if it's something obvious, don't discount that I've overlooked it for a reason.
C++? std::string. It's not going to destroy the performance on any modern computer.
However if you have some need to over-optimize this, you have three options:
Go with the buffer your example has.
Have the users delete the string afterwards. Many APIs like this provide their own delete function for deleting each kind of dynamically allocated return data.
Return a pointer to a static buffer which you fill in with the return string on each call. This does have some drawbacks, though, in that it's not thread safe, and it can be confusing because the returned pointer's value will change the next time someone calls the function. If non-thread-safety is acceptable and you document the limitations, it should be all right though.
If you are returning a point to a string constant, the caller will not have to delete the string - they'll only have to if you are new-ing the memory used by the string every time. If you're just returning a pointer to a string entry in a table of error messages, I would change the return type to TCHAR const * const and you should be OK.
Of course this will not prevent users of your code to attempt to delete the memory referenced by the pointer but there is only so much you can do to prevent abuse.
Just declare use a static string as a default result:
TCHAR* GetDirectShowMessageDisplayText( int messageNumber )
{
switch( messageNumber )
{
// ...
default:
static TCHAR[] default_value = "This is a default result...";
return default_value;
}
}
You may also declare "default_value" outside of the function.
UPDATE:
If you want to insert a message number in that string then it won't be thread-safe (if you are using multiple threads). However, the solution for that problem is to use thread-specific string. Here is an example using Boost.Thread:
#include <cstdio>
#include <boost/thread/tss.hpp>
#define TCHAR char // This is just because I don't have TCHAR...
static void errorMessageCleanup (TCHAR *msg)
{
delete []msg;
}
static boost::thread_specific_ptr<TCHAR> errorMsg (errorMessageCleanup);
static TCHAR *
formatErrorMessage (int number)
{
static const size_t MSG_MAX_SIZE = 256;
if (errorMsg.get () == NULL)
errorMsg.reset (new TCHAR [MSG_MAX_SIZE]);
snprintf (errorMsg.get (), MSG_MAX_SIZE, "Unexpected notification code (%d)", number);
return errorMsg.get ();
}
int
main ()
{
printf ("Message: %s\n", formatErrorMessage (1));
}
The only limitation of this solution is that returned string cannot be passed by the client to the other thread.
Perhaps have a static string buffer you return a pointer to:
std::ostringstream ss;
ss << "Unexpected notification code (" << messageNumber << ")";
static string temp = ss.str(); // static string always has a buffer
return temp.c_str(); // return pointer to buffer
This is not thread safe, and if you persistently hold the returned pointer and call it twice with different messageNumbers, they all point to the same buffer in temp - so both pointers now point to the same message. The solution? Return a std::string from the function - that's modern C++ style, try to avoid C style pointers and buffers. (It looks like you might want to invent a tstring which would be std::string in ANSI and std::wstring in unicode, although I'd recommend just going unicode-only... do you really have any reason to support non-unicode builds?)
You return some sort of self-releasing smart pointer or your own custom string class. You should follow the interface as it's defined in std::string for easiest use.
class bstr_string {
_bstr_t contents;
public:
bool operator==(const bstr_string& eq);
...
~bstr_string() {
// free _bstr_t
}
};
In C++, you never deal with raw pointers unless you have an important reason, you always use self-managing classes. Usually, Microsoft use raw pointers because they want their interfaces to be C-compatible, but if you don't care, then don't use raw pointers.
The simple solution does seem to be to just return a std::string. It does imply one dynamic memory allocation, but you'd probably get that in any case (as either the user or your function would have to make the allocation explicitly)
An alternative might be to allow the user to pass in an output iterator which you write the string into. Then the user is given complete control over how and when to allocate and store the string.
On the first go-round I missed that this was a C++ question rather than a plain C question. Having C++ to hand opens up another possibility: a self-managing pointer class that can be told whether or not to delete.
class MsgText : public boost::noncopyable
{
const char* msg;
bool shouldDelete;
public:
MsgText(const char *msg, bool shouldDelete = false)
: msg(msg), shouldDelete(shouldDelete)
{}
~MsgText()
{
if (shouldDelete)
free(msg);
}
operator const char*() const
{
return msg;
}
};
const MsgText GetDirectShowMessageDisplayText(int messageNumber)
{
switch(messageNumber)
{
case EC_ACTIVATE:
return MsgText("A video window is being activated or deactivated.");
// etc
default: {
char *msg = asprintf("Undocumented message (%u)", messageNumber);
return MsgText(msg, true);
}
}
}
(I don't remember if Windows CRT has asprintf, but it's easy enough to rewrite the above on top of std::string if it doesn't.)
Note the use of boost::noncopyable, though - if you copy this kind of object you risk double frees. Unfortunately, that may cause problems with returning it from your message-pretty-printer function. I'm not sure what the right way to deal with that is, I'm not actually much of a C++ guru.
You already use _bstr_t, so if you can just return those directly:
_bstr_t GetDirectShowMessageDisplayText(int messageNumber);
If you need to build a different message at runtime you can pack it into a _bstr_t too. Now the ownership is clear and the use is still simple thanks to RAII.
The overhead is negligible (_bstr_t uses ref-counting) and the calling code can still use _bstr_ts conversion to wchar_t* and char* if needed.
There's no good answer here, but this kludge might suffice.
const char *GetDirectShowMessageDisplayText(int messageNumber)
{
switch(messageNumber)
{
// ...
default: {
static char defaultMessage[] = "Unexpected notification code #4294967296";
char *pos = defaultMessage + sizeof "Unexpected notification code #" - 1;
snprintf(pos, sizeof "4294967296" - 1, "%u", messageNumber);
return defaultMessage;
}
}
}
If you do this, callers must be aware that the string they get back from GetDirectShowMessageText might be clobbered by a subsequent call to the function. And it's not thread safe, obviously. But those might be acceptable limitations for your application.