compile error: namespace usage or lack thereof

This commit is contained in:
KjellKod 2013-11-02 21:04:44 -06:00
parent 81b6b91038
commit a69286399d
4 changed files with 124 additions and 127 deletions

View File

@ -5,20 +5,19 @@
* Created on October 26, 2013, 3:45 PM * Created on October 26, 2013, 3:45 PM
*/ */
//#include "g2log.hpp"
#include "g2LogMessageBuilder.hpp" #include "g2LogMessageBuilder.hpp"
#include "g2logmessageimpl.hpp" #include "g2logmessageimpl.hpp"
#include "g2log.hpp"
#include "g2logmessage.hpp" #include "g2logmessage.hpp"
#include <iostream>
#include <csignal> #include <csignal>
namespace g2 {
namespace g2 {
using namespace internal;
LogMessageBuilder::LogMessageBuilder(const std::string& file, const int line, LogMessageBuilder::LogMessageBuilder(const std::string& file, const int line,
const std::string& function, const LEVELS& level) const std::string& function, const LEVELS& level)
: _message(std::make_shared<LogMessageImpl>(file, line, function, level)) {} : _message(std::make_shared<LogMessageImpl>(file, line, function, level)) {
//: _message(new LogMessageImpl(file, line, function, level)) // }
//{}
LogMessageBuilder::~LogMessageBuilder() { LogMessageBuilder::~LogMessageBuilder() {
LogMessage log_entry(_message); LogMessage log_entry(_message);
@ -26,7 +25,7 @@ namespace g2 {
FatalMessageBuilder trigger({log_entry.toString(), SIGABRT}); FatalMessageBuilder trigger({log_entry.toString(), SIGABRT});
return; // FatalMessageBuilder will send to worker at scope exit return; // FatalMessageBuilder will send to worker at scope exit
} }
internal::saveMessage(log_entry); // message saved to g2LogWorker saveMessage(log_entry); // message saved to g2LogWorker
} }
LogMessageBuilder& LogMessageBuilder::setExpression(const std::string& boolean_expression) { LogMessageBuilder& LogMessageBuilder::setExpression(const std::string& boolean_expression) {
@ -40,17 +39,18 @@ namespace g2 {
/// FatalMessageBuilder /// FatalMessageBuilder
FatalMessageBuilder::FatalMessageBuilder(const std::string& exit_message, int fatal_signal) FatalMessageBuilder::FatalMessageBuilder(const std::string& exit_message, int fatal_signal)
:_exit_message(exit_message), _fatal_signal(fatal_signal) { } : _exit_message(exit_message), _fatal_signal(fatal_signal) {
}
FatalMessageBuilder::~FatalMessageBuilder() { FatalMessageBuilder::~FatalMessageBuilder() {
// At destruction, flushes fatal message to g2LogWorker // At destruction, flushes fatal message to g2LogWorker
// either we will stay here until the background worker has received the fatal // either we will stay here until the background worker has received the fatal
// message, flushed the crash message to the sinks and exits with the same fatal signal // message, flushed the crash message to the sinks and exits with the same fatal signal
//..... OR it's in unit-test mode then we throw a std::runtime_error (and never hit sleep) //..... OR it's in unit-test mode then we throw a std::runtime_error (and never hit sleep)
internal::fatalCall({_exit_message, _fatal_signal}); FatalMessage msg(_exit_message, _fatal_signal);
//internal::fatalCall({_exit_message, _fatal_signal});
internal::fatalCall(msg);
} }
} // g2 } // g2

View File

@ -13,36 +13,36 @@
#include "g2loglevels.hpp" #include "g2loglevels.hpp"
namespace g2 {struct LogMessageImpl; namespace g2 {
// At RAII scope end this struct will trigger a FatalMessage sending struct LogMessageImpl;
struct FatalMessageBuilder {
//explicit FatalMessageBuilder(const FatalMessage& exit_message);
FatalMessageBuilder(const std::string& exit_message, int fatal_signal);
~FatalMessageBuilder();
std::string _exit_message;
int _fatal_signal;
};
// At RAII scope end this struct will trigger a FatalMessage sending
struct FatalMessageBuilder {
//explicit FatalMessageBuilder(const FatalMessage& exit_message);
FatalMessageBuilder(const std::string& exit_message, int fatal_signal);
virtual ~FatalMessageBuilder();
struct LogMessageBuilder { std::string _exit_message;
LogMessageBuilder(const std::string& file, const int line, const std::string& function, const LEVELS& level); int _fatal_signal;
virtual ~LogMessageBuilder(); };
LogMessageBuilder& setExpression(const std::string& boolean_expression); struct LogMessageBuilder {
std::ostringstream& stream(); LogMessageBuilder(const std::string& file, const int line, const std::string& function, const LEVELS& level);
virtual ~LogMessageBuilder();
// Use "-Wall" to generate warnings in case of illegal printf format. LogMessageBuilder& setExpression(const std::string& boolean_expression);
// Ref: http://www.unixwiz.net/techtips/gnu-c-attributes.html std::ostringstream& stream();
// Use "-Wall" to generate warnings in case of illegal printf format.
// Ref: http://www.unixwiz.net/techtips/gnu-c-attributes.html
#ifndef __GNUC__ #ifndef __GNUC__
#define __attribute__(x) // Disable 'attributes' if compiler does not support 'em #define __attribute__(x) // Disable 'attributes' if compiler does not support 'em
#endif #endif
void messageSave(const char *printf_like_message, ...) void messageSave(const char *printf_like_message, ...)
__attribute__((format(printf, 2, 3))); // ref: http://www.codemaestro.com/reviews/18 __attribute__((format(printf, 2, 3))); // ref: http://www.codemaestro.com/reviews/18
private:
std::shared_ptr<LogMessageImpl> _message;
};
private:
std::shared_ptr<LogMessageImpl> _message;
};
} // g2 } // g2

View File

@ -44,43 +44,41 @@ class g2LogWorker;
* --- Thanks for a great 2011 and good luck with 'g2' --- KjellKod * --- Thanks for a great 2011 and good luck with 'g2' --- KjellKod
*/ */
namespace g2 { namespace g2 {
struct LogMessage; struct LogMessage;
struct FatalMessage; struct FatalMessage;
/** Should be called at very first startup of the software with \ref g2LogWorker /** Should be called at very first startup of the software with \ref g2LogWorker
* pointer. Ownership of the \ref g2LogWorker is the responsibilkity of the caller */ * pointer. Ownership of the \ref g2LogWorker is the responsibilkity of the caller */
void initializeLogging(g2LogWorker *logger); void initializeLogging(g2LogWorker *logger);
namespace internal { namespace internal {
// Save the created LogMessage to any existing sinks bool isLoggingInitialized();
void saveMessage(g2::LogMessage log_entry);
// Save the created FatalMessage to any existing sinks and exit with // Save the created LogMessage to any existing sinks
// the originating fatal signal,. or SIGABRT if it originated from a broken contract void saveMessage(LogMessage log_entry);
void fatalCall(FatalMessage message);
// Save the created FatalMessage to any existing sinks and exit with
// the originating fatal signal,. or SIGABRT if it originated from a broken contract
void fatalCall(FatalMessage message);
/** FOR TESTING PURPOSES /** FOR TESTING PURPOSES
* Shutdown the logging by making the pointer to the background logger to nullptr * Shutdown the logging by making the pointer to the background logger to nullptr
* The \ref pointer to the g2LogWorker is owned by the instantniater \ref initializeLogging * The \ref pointer to the g2LogWorker is owned by the instantniater \ref initializeLogging
* and is not deleted. By restoring the ptr to nullptr we can re-initialize it later again. * and is not deleted. By restoring the ptr to nullptr we can re-initialize it later again.
* *
* This is kept for test reasons and should normally not be used */ * This is kept for test reasons and should normally not be used */
g2LogWorker* shutDownLogging(); g2LogWorker* shutDownLogging();
bool isLoggingInitialized(); /** FOR TESTING PURPOSES: @ref g2log.ipp
* By default the g2log will call g2LogWorker::fatal(...) which will
* abort() the system after flushing the logs to file. This makes unit
/** FOR TESTING PURPOSES: @ref g2log.ipp * test of FATAL level cumbersome. A work around is to change the
* By default the g2log will call g2LogWorker::fatal(...) which will * fatal call' which can be done here */
* abort() the system after flushing the logs to file. This makes unit void changeFatalInitHandlerForUnitTesting();
* test of FATAL level cumbersome. A work around is to change the } // g2::internal
* fatal call' which can be done here */
void changeFatalInitHandlerForUnitTesting();
} // g2::internal
} // g2 } // g2

View File

@ -20,76 +20,75 @@
#include <chrono> #include <chrono>
namespace g2 { namespace g2 {
namespace internal { namespace internal {
g2LogWorker* g_logger_instance = nullptr; // instantiated and OWNED somewhere else (main) g2LogWorker* g_logger_instance = nullptr; // instantiated and OWNED somewhere else (main)
std::string g_once_error; std::string g_once_error;
std::once_flag g_error_flag; std::once_flag g_error_flag;
std::once_flag g_retrieve_error_flag; std::once_flag g_retrieve_error_flag;
}
/**
* saveMesage to the LogWorker which will pass them to the sinks.
*
* In the messup of calling LOG before instantiating the logger the first
* message will be saved,.. to be given later with an initialization warning
*/
void saveMessage(g2::LogMessage log_entry) {
using namespace internal;
/** if (false == isLoggingInitialized()) {
* saveMesage to the LogWorker which will pass them to the sinks. std::call_once(g_error_flag, [&]() {
* g_once_error = {"\n\nWARNING LOGGER NOT INSTANTIATED WHEN CALLING IT"
* In the messup of calling LOG before instantiating the logger the first "\nAt least once tried to call the logger before instantiating it\n\n"};
* message will be saved,.. to be given later with an initialization warning g_once_error.append("\nThe first message was: \n").append(log_entry.toString());
*/ });
void saveMessage(g2::LogMessage log_entry) { std::cerr << g_once_error << std::endl;
using namespace internal; return;
}
if (false == isLoggingInitialized()) {
std::call_once(g_error_flag, [&]() { std::call_once(g_retrieve_error_flag, [&]() {
g_once_error = {"\n\nWARNING LOGGER NOT INSTANTIATED WHEN CALLING IT" if (false == g_once_error.empty()) {
"\nAt least once tried to call the logger before instantiating it\n\n"}; std::string empty = {""};
g_once_error.append("\nThe first message was: \n").append(log_entry.toString()); g2::LogMessage error{std::make_shared<g2::LogMessageImpl>(empty, 0, empty, WARNING)};
}); error.stream() << g_once_error;
std::cerr << g_once_error << std::endl; g_logger_instance->save(error);
return; }
} });
std::call_once(g_retrieve_error_flag, [&]() { g_logger_instance->save(log_entry);
if (false == g_once_error.empty()) {
std::string empty = {""};
g2::LogMessage error{std::make_shared<g2::LogMessageImpl>(empty, 0, empty, WARNING)};
error.stream() << g_once_error;
g_logger_instance->save(error);
} }
});
g_logger_instance->save(log_entry);
}
void fatalCallToLogger(FatalMessage message) { void fatalCallToLogger(FatalMessage message) {
// real fatal call to loggr // real fatal call to loggr
internal::g_logger_instance->fatal(message); internal::g_logger_instance->fatal(message);
} }
// By default this function pointer goes to \ref fatalCall; // By default this function pointer goes to \ref fatalCall;
void (*g_fatal_to_g2logworker_function_ptr)(FatalMessage) = fatalCallToLogger; void (*g_fatal_to_g2logworker_function_ptr)(FatalMessage) = fatalCallToLogger;
void fatalCallForUnitTest(FatalMessage fatal_message) { void fatalCallForUnitTest(FatalMessage fatal_message) {
// mock fatal call, not to logger: used by unit test // mock fatal call, not to logger: used by unit test
assert(internal::g_logger_instance != nullptr); assert(internal::g_logger_instance != nullptr);
internal::g_logger_instance->save(fatal_message.copyToLogMessage()); // calling 'save' instead of 'fatal' internal::g_logger_instance->save(fatal_message.copyToLogMessage()); // calling 'save' instead of 'fatal'
throw std::runtime_error(fatal_message.toString()); throw std::runtime_error(fatal_message.toString());
} }
/** The default, initial, handling to send a 'fatal' event to g2logworker /** The default, initial, handling to send a 'fatal' event to g2logworker
* he caller will stay here, eternally, until the software is aborted * he caller will stay here, eternally, until the software is aborted
* During unit testing the sleep-loop will be interrupted by exception from * During unit testing the sleep-loop will be interrupted by exception from
* @ref fatalCallForUnitTest */ * @ref fatalCallForUnitTest */
void fatalCall(FatalMessage message) { void fatalCall(FatalMessage message) {
g_fatal_to_g2logworker_function_ptr(message); g_fatal_to_g2logworker_function_ptr(message);
while (true) { while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1));
} }
} }
/** Used to REPLACE fatalCallToLogger for fatalCallForUnitTest /** Used to REPLACE fatalCallToLogger for fatalCallForUnitTest
* This function switches the function pointer so that only * This function switches the function pointer so that only
* 'unitTest' mock-fatal calls are made. */ * 'unitTest' mock-fatal calls are made. */
void changeFatalInitHandlerForUnitTesting() { void changeFatalInitHandlerForUnitTesting() {
g_fatal_to_g2logworker_function_ptr = fatalCallForUnitTest; g_fatal_to_g2logworker_function_ptr = fatalCallForUnitTest;
} }
} // internal
} // g2 } // g2