diff --git a/ACE/ace/ACE.cpp b/ACE/ace/ACE.cpp index 6926a52338e2d..b3c98d5937a5e 100644 --- a/ACE/ace/ACE.cpp +++ b/ACE/ace/ACE.cpp @@ -2389,7 +2389,7 @@ ACE::timestamp (ACE_TCHAR date_and_time[], } /// Returns the given timestamp in the form -/// "hour:minute:second:microsecond." The month, day, and year are +/// "hour:minute:second.microsecond." The month, day, and year are /// also stored in the beginning of the date_and_time array /// using ISO-8601 format. /// 012345678901234567890123456 @@ -2430,6 +2430,39 @@ ACE::timestamp (const ACE_Time_Value& time_value, return &date_and_time[10 + (return_pointer_to_first_digit != 0)]; } +/// Returns the given duration in the form +/// "hour:minute:second.microsecond." +/// 0123456789012345 +/// 12:56:00.123456 +ACE_TCHAR * +ACE::duration (const ACE_Time_Value& duration_value, + ACE_TCHAR duration[], + size_t duration_len) +{ + //ACE_TRACE ("ACE::duration"); + + // This magic number is from the formatting statement + // farther down this routine. + if (duration_len < 16) + { + errno = EINVAL; + return 0; + } + + time_t secs = duration_value.sec (); + struct tm tms; + ACE_OS::gmtime_r (&secs, &tms); + ACE_OS::snprintf (duration, + duration_len, + ACE_TEXT ("%2.2d:%2.2d:%2.2d.%06ld"), + tms.tm_hour, + tms.tm_min, + tms.tm_sec, + static_cast (duration_value.usec ())); + duration[duration_len - 1] = '\0'; + return &duration[0]; +} + /// This function rounds the request to a multiple of the page size. size_t ACE::round_to_pagesize (size_t len) diff --git a/ACE/ace/ACE.h b/ACE/ace/ACE.h index b705e092d9556..2ebba0b66f707 100644 --- a/ACE/ace/ACE.h +++ b/ACE/ace/ACE.h @@ -478,7 +478,8 @@ namespace ACE * Translate the given timestamp to ISO-8601 format. * * @param time_value ACE_Time_Value to format. This is assumed to be - * an absolute time value. + * an absolute time value. Passing ACE_Time_Value::zero + uses gettimeofday(). * @param date_and_time Array to hold the timestamp. * @param time_len Size of @a date_and_time in ACE_TCHARs. * Must be greater than or equal to 27. @@ -498,6 +499,24 @@ namespace ACE size_t time_len, bool return_pointer_to_first_digit = false); + /** + * Translate the given duration to ISO-8601 format. Note that the current + * implementation cannot handle durations larger or equal to 24 hours. + * + * @param duration_value ACE_Time_Value to format. This is assumed to be + * a time period. + * @param duration Array to hold the duration. + * @param duration_len Size of @a duration in ACE_TCHARs. + * Must be greater than or equal to 16. + * + * @retval 0 if unsuccessful, with errno set. If @a duration_len is less than + * 16 errno will be EINVAL. + * @retval If successful, pointer to beginning of @a duration. + */ + extern ACE_Export ACE_TCHAR *duration (const ACE_Time_Value& duration_value, + ACE_TCHAR duration[], + size_t duration_len); + /** * Translate the current time to ISO-8601 timestamp format. * diff --git a/ACE/ace/Log_Msg.cpp b/ACE/ace/Log_Msg.cpp index 1abe5c7e0b3c8..d94c31edb9c7a 100644 --- a/ACE/ace/Log_Msg.cpp +++ b/ACE/ace/Log_Msg.cpp @@ -1726,6 +1726,37 @@ ACE_Log_Msg::log (const ACE_TCHAR *format_str, break; } + case 'Y': // Format the duration in hour:minute:sec.usec format. + // Note that this currently overflows if the provided + // duration is larger or equal to 24 hours. + { + ACE_TCHAR duration[16]; + ACE_OS::strcpy (fp, ACE_TEXT_PRIs); + // Did we find the flag indicating a time value argument + if (format[1] == ACE_TEXT('#')) + { + ACE_Time_Value* duration_value = va_arg (argp, ACE_Time_Value*); + if (can_check) + this_len = ACE_OS::snprintf + (bp, bspace, format, + ACE::duration (*duration_value, + duration, + sizeof duration / sizeof (ACE_TCHAR))); + else + this_len = ACE_OS::sprintf + (bp, format, ACE::duration (*duration_value, + duration, + sizeof duration / sizeof (ACE_TCHAR))); + } + else + { + ACE_OS::fprintf (stderr, + "error: %%Y requires # modifier\n"); + } + ACE_UPDATE_COUNT (bspace, this_len); + break; + } + case 't': // Format thread id. #if defined (ACE_WIN32) ACE_OS::strcpy (fp, ACE_TEXT ("u")); @@ -2415,6 +2446,14 @@ bool ACE_Log_Formatter::process_conversion () this->bp_ += len; } break; + // %Y with # in the conversion spec takes an arg (ACE_Time_Value*) + case 'Y': + ACE_OS::strcpy (this->fp_, "s"); + if (ACE_OS::memchr (this->fmt_out_, '#', this->fp_ - this->fmt_out_)) + return false; + ACE_OS::fprintf (stderr, + "error: %%Y requires # modifier\n"); + break; case '{': this->logger_->inc (); diff --git a/ACE/ace/Log_Msg.h b/ACE/ace/Log_Msg.h index ebbac05573a03..ac48b5ce9cc70 100644 --- a/ACE/ace/Log_Msg.h +++ b/ACE/ace/Log_Msg.h @@ -542,7 +542,7 @@ class ACE_Export ACE_Log_Msg * - 'S': print out the appropriate signal message corresponding * to var-argument, e.g., as done by strsignal() * - 's': prints a ACE_TCHAR* character string (also see C and W) - * - 'T': print timestamp in hour:minute:sec:usec format (plain option, + * - 'T': print timestamp in hour:minute:sec.usec format (plain option, * i.e. without any flags, prints system supplied timestamp; * with '#' flag added expects ACE_Time_Value* in argument list) * - 'D': print timestamp as Weekday Month day year hour:minute:sec.usec @@ -555,6 +555,10 @@ class ACE_Export ACE_Log_Msg * - 'W': prints a wchar_t* character string (also see C and s) * - 'x': print as a hex number * - 'X': print as a hex number + * - 'Y': print duration in hour:minute:sec.usec format (plain option, + * i.e. without any flags, is currently unspecified; + * with '#' flag added expects ACE_Time_Value* in argument list) + * Note that durations >= 24 hours will currently overflow * - 'z': print an ACE_OS::WChar character * - 'Z': print an ACE_OS::WChar character string * - ':': print a time_t value as an integral number