Jump to content
  • Advertisement
Sign in to follow this  
iliak

#define question

This topic is 4836 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi To avoid typing too much, I'm so lazy ;), I made the following macro :
#define	TODO(x)	DebugManager->Print(Todo, __FUNCTION__, "%s (line %i)",(x), __LINE__);

// case 1
TODO("All good")

// case 2
TODO("file \"%s\" not found", "toto.txt")

Case 1 print "All good (line 123)" Case 2 raises [Compiler Warning (level 1) C4002] : Too much parameters Can someone help me to find t he good define ? Thx

Share this post


Link to post
Share on other sites
Advertisement
I believe you have to define it something like #define TODO(x...)

Although what you're doing with it is retarded.

Subbing in x for "("file \"%s\" not found", "toto.txt"" you get:

DebugManager->Print(Todo, __FUNCTION__, "%s (line %i)",("file \"%s\" not found", "toto.txt"), __LINE__);

Share this post


Link to post
Share on other sites
Quote:
Original post by K4W4H33
I believe you have to define it something like #define TODO(x...)


I don't believe you can do variable length macro definitions...at least not in MSVC. Which IDE is the OP using?

Share this post


Link to post
Share on other sites
You can't do variable length macros. Assuming you are using C++ you can do this:

#define TODO(x) std::cout << x << "(line " << __LINE__ << ")";

//case 2
TODO("file \"" << "toto.txt" << "\" not found");

//case 2 expands to:
std::cout << "file \"" << "toto.txt" << "\" not found" << "(line " << __LINE__ << ")";




Share this post


Link to post
Share on other sites
try something like this:



/////////////////////////////////////////////
/////////////////////////////////////////////
// ... [log.h] file
/////////////////////////////////////////////
/////////////////////////////////////////////

/////////////////////////////////////////////
// log_source
// - stores data of where the most recent
// log was made
/////////////////////////////////////////////
struct log_source
{
string m_file;
string m_function;
int m_line;
};

/////////////////////////////////////////////
// globably declared log_source object
/////////////////////////////////////////////
singleton<log_source> g_log_source;

/////////////////////////////////////////////
// log_event macro
/////////////////////////////////////////////
#define log_event \
g_log_source->m_file = __FILE__; \
g_log_source->m_function = __FUNCTION__; \
g_log_source->m_line = __LINE__; \
log

/////////////////////////////////////////////
// log
// - now when you define log, it has to
// take into account that the
// g_log_source exist and assume it is
// up to date
/////////////////////////////////////////////
void log(string v_format, ...)
{
/////////////////////////////////////////////
// create g_log_source message header
string o_header = string("\nlog: ") +
" file: " + g_log_source->m_file +
" function: " + g_log_source->m_function +
" line: [" + g_log_source->m_line + "]";
// + get_date();

/////////////////////////////////////////////
// print out to log file
va_list o_va_list;
va_start(o_va_list, v_format);

FILE o_log_file = ...; //get_log_file();
vfprintf(o_log_file, o_header + v_format, o_va_list);

va_end(o_va_list);
}

/////////////////////////////////////////////
/////////////////////////////////////////////
// [main.h] file
/////////////////////////////////////////////
/////////////////////////////////////////////
#include [log.h]

void main()
{
log_event("\nhello world. the year is: %d",2005);
}





the magic here is that the log_event macro called in main really doesn't
have a parameter list. the parameter list really gets passed to the
'log' function tagged on to the end of the log_event macro definition.

the log_event macro is really only needed to set the __LINE__, etc to the
global (singleton) g_log_source structure for propper reading in the actual
logging function.

illone

Share this post


Link to post
Share on other sites
Here's one quick and very simple approach to deal with this...

#ifdef _DEBUG

class Logger {

class SubLogger {
const char *currentFilename;
int currentLineNo;

public:
void operator()(const char *fmt, ...) {
// main logging code here
};

SubLogger &setLocation(const char *filename, int lineno) {
currentFilename = filename;
currentLineNo = lineno;
return *this;
}

};

SubLogger subLogger;

public:

SubLogger &operator()(const char *filename, int lineno) {
return subLogger.setLocation(filename, lineno);
}
};

Logger logger;

#define LOGGER(x) logger(__FILE__, __LINE__) x
#else
#define LOGGER(x)
#endif

void function(const char *ptr)
{
LOGGER(("log message here %s", ptr));
}



By using parents in the macro argument itself it expands to:

logger(__FILE__,__LINE__) ("log message here %s", ptr) ;


Share this post


Link to post
Share on other sites
And here's another one (which I posted like two days ago):
#ifndef NDEBUG
struct log {
log(const char *file, unsigned line) {
fprintf(stderr, "%s[%d] :: ", file, line);
}

void message(const char *format, ...) {
va_list args;

va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fputc('\n', stderr);
}
};
# define log log(__FILE__, __LINE__).message
#else
struct log_dummy_t { };
inline log_dummy_t log(const char *format, ...) { return log_dummy_t; }
# define log , true ? log_dummy_t : log
#endif

// invoked like this
log("%s %d", "abc", 123);

edit: I hope this version will prevent most kinds of abuse of the release version..

[Edited by - doynax on July 20, 2005 8:38:17 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!