summaryrefslogtreecommitdiff
path: root/ACE/ace/Log_Msg.h
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/Log_Msg.h')
-rw-r--r--ACE/ace/Log_Msg.h200
1 files changed, 195 insertions, 5 deletions
diff --git a/ACE/ace/Log_Msg.h b/ACE/ace/Log_Msg.h
index 4281ece6417..25b62ddac53 100644
--- a/ACE/ace/Log_Msg.h
+++ b/ACE/ace/Log_Msg.h
@@ -23,6 +23,7 @@
#include "ace/Log_Priority.h"
#include "ace/os_include/os_limits.h"
#include "ace/Synch_Traits.h"
+#include "ace/Basic_Types.h"
// The ACE_ASSERT macro used to be defined here, include ace/Assert.h
// for backwards compatibility.
@@ -71,32 +72,63 @@
} while (0)
#endif
#if !defined (ACE_ERROR_RETURN)
-#define ACE_ERROR_RETURN(X, Y) \
+# ifdef ACE_LACKS_VA_FUNCTIONS
+# define ACE_ERROR_RETURN(X, Y) \
do { \
int const __ace_error = ACE_Log_Msg::last_error_adapter (); \
ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \
ace___->conditional_set (__FILE__, __LINE__, Y, __ace_error); \
- ace___->log X; \
+ ace___->log (X); \
return Y; \
} while (0)
+# else /* ACE_LACKS_VA_FUNCTIONS */
+# define ACE_ERROR_RETURN(X, Y) \
+ do { \
+ int __ace_error = ACE_Log_Msg::last_error_adapter (); \
+ ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \
+ ace___->conditional_set (__FILE__, __LINE__, Y, __ace_error); \
+ ace___->log X; \
+ return Y; \
+ } while (0)
+# endif /* ACE_LACKS_VA_FUNCTIONS */
#endif
#if !defined (ACE_ERROR)
-#define ACE_ERROR(X) \
+# ifdef ACE_LACKS_VA_FUNCTIONS
+# define ACE_ERROR(X) \
do { \
int const __ace_error = ACE_Log_Msg::last_error_adapter (); \
ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \
ace___->conditional_set (__FILE__, __LINE__, -1, __ace_error); \
+ ace___->log (X); \
+ } while (0)
+# else /* ACE_LACKS_VA_FUNCTIONS */
+# define ACE_ERROR(X) \
+ do { \
+ int __ace_error = ACE_Log_Msg::last_error_adapter (); \
+ ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \
+ ace___->conditional_set (__FILE__, __LINE__, -1, __ace_error); \
ace___->log X; \
} while (0)
+# endif /* ACE_LACKS_VA_FUNCTIONS */
#endif
#if !defined (ACE_DEBUG)
-#define ACE_DEBUG(X) \
+# ifdef ACE_LACKS_VA_FUNCTIONS
+# define ACE_DEBUG(X) \
do { \
int const __ace_error = ACE_Log_Msg::last_error_adapter (); \
ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \
ace___->conditional_set (__FILE__, __LINE__, 0, __ace_error); \
+ ace___->log (X); \
+ } while (0)
+# else /* ACE_LACKS_VA_FUNCTIONS */
+# define ACE_DEBUG(X) \
+ do { \
+ int __ace_error = ACE_Log_Msg::last_error_adapter (); \
+ ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \
+ ace___->conditional_set (__FILE__, __LINE__, 0, __ace_error); \
ace___->log X; \
} while (0)
+# endif /* ACE_LACKS_VA_FUNCTIONS */
#endif
#if !defined (ACE_ERROR_INIT)
#define ACE_ERROR_INIT(VALUE, FLAGS) \
@@ -143,6 +175,7 @@ class ACE_Thread_Descriptor;
class ACE_Log_Record;
class ACE_Log_Category_TSS;
template<typename M, typename T> class ACE_Atomic_Op;
+class ACE_Log_Formatter;
/**
* @class ACE_Log_Msg
@@ -428,12 +461,14 @@ public:
/// Return true if the requested priority is enabled.
int log_priority_enabled (ACE_Log_Priority log_priority);
+#ifndef ACE_LACKS_VA_FUNCTIONS
/// Return true if the requested priority is enabled.
int log_priority_enabled (ACE_Log_Priority log_priority,
const char *,
...);
+#endif
-#if defined (ACE_USES_WCHAR)
+#if defined (ACE_USES_WCHAR) && !defined ACE_LACKS_VA_FUNCTIONS
// We are not using ACE_TCHAR for this since ACE_HEX_DUMP
// doesn't take in a ACE_TCHAR. log_hexdump takes in a char
// string, so this must be able to take in a char string even
@@ -474,6 +509,7 @@ public:
int op_status,
int errnum);
+#ifndef ACE_LACKS_VA_FUNCTIONS
/**
* Format a message to the thread-safe ACE logging mechanism. Valid
* options (prefixed by '%', as in printf format strings) include:
@@ -531,6 +567,13 @@ public:
ssize_t log (ACE_Log_Priority priority, const ACE_ANTI_TCHAR *format, ...);
#endif /* ACE_HAS_WCHAR */
+#else /* ACE_LACKS_VA_FUNCTIONS */
+ friend class ACE_Log_Formatter;
+
+ ssize_t log (const ACE_Log_Formatter &formatter);
+
+#endif /* ACE_LACKS_VA_FUNCTIONS */
+
/**
* An alternative logging mechanism that makes it possible to
* integrate variable argument lists from other logging mechanisms
@@ -716,6 +759,153 @@ private:
ACE_Log_Msg (const ACE_Log_Msg &);
};
+
+#ifdef ACE_LACKS_VA_FUNCTIONS
+class ACE_Time_Value;
+/// Alternative to varargs for formatting log messages.
+/// When this implementation is enabled, the logging macros (ACE_DEBUG, etc.)
+/// are modified to change from logger->log(LM_FOO, "fmt_str", arg1, arg2) to
+/// logger->log((LM_FOO, "fmt_str", arg1, arg2)). Due to the extra set of
+/// parens, the various overloaded comma operators below take the place of the
+/// varargs function. The first operator called is the non-member
+/// operator,(ACE_Log_Priority, const char*) which returns an ACE_Log_Formatter
+/// object. The subsequent comma operators (for the actual variable args) are
+/// members of the ACE_Log_Formatter class.
+class ACE_Export ACE_Log_Formatter
+{
+public:
+ ACE_Log_Formatter (ACE_Log_Priority prio, const char *fmt);
+
+ // Notes:
+ // - ACE_OS::snprintf() is assumed to work. The fallback to ACE_OS::sprintf()
+ /// is not implemented.
+ // - Other than special cases (listed below), the names of the parameters
+ // indicate which formatters they are used for (pct_c => %c).
+ // - size_t (%B), ssize_t (%b), and time_t (%:) will use one of the
+ // other overloads (int, INT64, UINT64) depending on the platform.
+ // - %*s (etc) uses the int or uint overloads for the size argument.
+ // - No support for ACE_USES_WCHAR has been attempted.
+ // - Not all platform-specific features from the varargs implementation have
+ // been ported over to this implementation.
+
+ ACE_Log_Formatter &operator, (int pct_adiRS);
+
+ ACE_Log_Formatter &operator, (unsigned int pct_ouxX);
+
+ ACE_Log_Formatter &operator, (double pct_AeEfFgG);
+
+ ACE_Log_Formatter &operator, (long double pct_AeEfFgG);
+
+ ACE_Log_Formatter &operator, (char pct_c);
+
+ ACE_Log_Formatter &operator, (const char *pct_Cps);
+
+ ACE_Log_Formatter &operator, (ACE_INT64 pct_q);
+
+ ACE_Log_Formatter &operator, (ACE_UINT64 pct_Q);
+
+ ACE_Log_Formatter &operator, (void (*pct_r) ());
+
+ ACE_Log_Formatter &operator, (ACE_WCHAR_T pct_wz);
+
+ ACE_Log_Formatter &operator, (const ACE_WCHAR_T *pct_WZ);
+
+ ACE_Log_Formatter &operator, (const void *pct_at);
+
+ ACE_Log_Formatter &operator, (const ACE_Time_Value *pct_DT);
+
+#if ACE_SIZEOF_LONG == 4
+ ACE_Log_Formatter &operator, (long pct_Lmodifier);
+
+ ACE_Log_Formatter &operator, (unsigned long pct_Lmodifier);
+#endif
+
+ bool abort () const { return this->abort_; }
+
+ int saved_errno () const { return this->saved_errno_; }
+
+ bool to_record (ACE_Log_Record &record);
+
+ ACE_Log_Priority priority () const { return this->priority_; }
+
+private:
+ /// Parse the format_ string up to the point where an argument is needed.
+ /// Set up fmt_out_ as a format string that goes out to snprintf.
+ void prepare_format ();
+
+ /// Helper function for prepare_format. Processes as much of one conversion
+ /// specification as possible. Returns true if prepare_format can continue
+ /// parsing, false if prepare_format needs to return to get more input.
+ bool process_conversion ();
+
+ /// Copy up to 'limit' characters of 'str' to the resulting buffer (bp_).
+ /// Returns the number of characters copied.
+ int copy_trunc (const char *str, int limit);
+
+ /// Insert one argument into the formatted buffer.
+ /// arg is not a pointer (pointers use the overload below).
+ /// If allow_star is true, the argument can be the length for a conversion
+ /// that uses the '*' for width or precision.
+ template <typename ArgT>
+ void insert_arg (ArgT arg, bool allow_star = false);
+
+ /// Insert one pointer-typed argument into the formatted buffer.
+ /// These could be strings (so ArgT is const char or const wchar_t) or void*.
+ template <typename ArgT>
+ void insert_arg (ArgT *arg);
+
+ /// Core functionality common to both insert_arg overloads.
+ template <typename ArgT>
+ void insert_arg_i (ArgT arg);
+
+ /// Insert the %S (signal name) conversion specification into the buffer.
+ void insert_pct_S (int sig);
+
+ /// Save errno at the start of the log formatting so it can be restored later.
+ const int saved_errno_;
+
+ /// Priority of this message.
+ const ACE_Log_Priority priority_;
+
+ /// Remaining format string (from user) that's left to process.
+ const char *format_;
+
+ /// The ACE_Log_Msg object that this formatter works with.
+ ACE_Log_Msg *const logger_;
+
+ /// Saved state of the %a (abort) processing.
+ enum { ABRT_NONE, ABRT_AFTER_FORMAT, ABRT_NEED_ARG } abort_;
+
+ /// The current log priority is enabled on the logger object.
+ bool enabled_;
+
+ /// Which specifier is currently being processed (' ' for none).
+ char in_prog_;
+
+ /// The value last read in from the "varargs" for '*' in width or precision.
+ int last_star_;
+
+ /// Buffer pointer into ACE_Log_Msg's resulting buffer.
+ char *bp_;
+
+ /// Buffer space available for bp_ to advance.
+ size_t bspace_;
+
+ /// Local buffer for outgoing (given to snprintf) format strings.
+ char fmt_out_[128];
+
+ /// Format pointer: current position in fmt_out_.
+ char *fp_;
+
+ /// Saved value of ACE_Log_Msg::msg_off_ in case of reentrant logging (%r).
+ ptrdiff_t offset_;
+};
+
+ACE_Export
+ACE_Log_Formatter operator, (ACE_Log_Priority prio, const char *fmt);
+
+#endif /* ACE_LACKS_VA_FUNCTIONS */
+
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)