diff --git a/capinfos.c b/capinfos.c index 7f7e867f9b..bf96c030d3 100644 --- a/capinfos.c +++ b/capinfos.c @@ -339,68 +339,13 @@ absolute_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info) if (cf_info->times_known && cf_info->packet_count > 0) { if (time_as_secs) { - switch (tsprecision) { - - case WTAP_TSPREC_SEC: - snprintf(time_string_buf, sizeof time_string_buf, - "%"PRId64, - (gint64)timer->secs); - break; - - case WTAP_TSPREC_DSEC: - snprintf(time_string_buf, sizeof time_string_buf, - "%"PRId64"%s%01d", - (gint64)timer->secs, - decimal_point, - timer->nsecs / 100000000); - break; - - case WTAP_TSPREC_CSEC: - snprintf(time_string_buf, sizeof time_string_buf, - "%"PRId64"%s%02d", - (gint64)timer->secs, - decimal_point, - timer->nsecs / 10000000); - break; - - case WTAP_TSPREC_MSEC: - snprintf(time_string_buf, sizeof time_string_buf, - "%"PRId64"%s%03d", - (gint64)timer->secs, - decimal_point, - timer->nsecs / 1000000); - break; - - case WTAP_TSPREC_USEC: - snprintf(time_string_buf, sizeof time_string_buf, - "%"PRId64"%s%06d", - (gint64)timer->secs, - decimal_point, - timer->nsecs / 1000); - break; - - case WTAP_TSPREC_NSEC: - snprintf(time_string_buf, sizeof time_string_buf, - "%"PRId64"%s%09d", - (gint64)timer->secs, - decimal_point, - timer->nsecs); - break; - - default: - snprintf(time_string_buf, sizeof time_string_buf, - "Unknown precision %d", - tsprecision); - break; - } - return time_string_buf; + display_epoch_time(time_string_buf, sizeof time_string_buf, timer, tsprecision); } else { format_nstime_as_iso8601(time_string_buf, sizeof time_string_buf, timer, decimal_point, TRUE, tsprecision); - return time_string_buf; } + } else { + snprintf(time_string_buf, sizeof time_string_buf, "n/a"); } - - snprintf(time_string_buf, sizeof time_string_buf, "n/a"); return time_string_buf; } @@ -421,72 +366,56 @@ relative_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info, gb static gchar time_string_buf[39]; if (cf_info->times_known && cf_info->packet_count > 0) { - switch (tsprecision) { + char *ptr; + size_t remaining; + int num_bytes; - case WTAP_TSPREC_SEC: - snprintf(time_string_buf, sizeof time_string_buf, - "%"PRId64"%s%s", - (gint64)timer->secs, - second, - timer->secs == 1 ? "" : plural); - break; - - case WTAP_TSPREC_DSEC: - snprintf(time_string_buf, sizeof time_string_buf, - "%"PRId64"%s%01d%s%s", - (gint64)timer->secs, - decimal_point, - timer->nsecs / 100000000, - second, - (timer->secs == 1 && timer->nsecs == 0) ? "" : plural); - break; - - case WTAP_TSPREC_CSEC: - snprintf(time_string_buf, sizeof time_string_buf, - "%"PRId64"%s%02d%s%s", - (gint64)timer->secs, - decimal_point, - timer->nsecs / 10000000, - second, - (timer->secs == 1 && timer->nsecs == 0) ? "" : plural); - break; - - case WTAP_TSPREC_MSEC: - snprintf(time_string_buf, sizeof time_string_buf, - "%"PRId64"%s%03d%s%s", - (gint64)timer->secs, - decimal_point, - timer->nsecs / 1000000, - second, - (timer->secs == 1 && timer->nsecs == 0) ? "" : plural); - break; - - case WTAP_TSPREC_USEC: - snprintf(time_string_buf, sizeof time_string_buf, - "%"PRId64"%s%06d%s%s", - (gint64)timer->secs, - decimal_point, - timer->nsecs / 1000, - second, - (timer->secs == 1 && timer->nsecs == 0) ? "" : plural); - break; - - case WTAP_TSPREC_NSEC: - snprintf(time_string_buf, sizeof time_string_buf, - "%"PRId64"%s%09d%s%s", - (gint64)timer->secs, - decimal_point, - timer->nsecs, - second, - (timer->secs == 1 && timer->nsecs == 0) ? "" : plural); - break; - - default: - snprintf(time_string_buf, sizeof time_string_buf, - "Unknown precision %d", - tsprecision); - break; + ptr = time_string_buf; + remaining = sizeof time_string_buf; + num_bytes = snprintf(ptr, remaining, + "%"PRId64, + (gint64)timer->secs); + if (num_bytes < 0) { + /* + * That got an error. + * Not much else we can do. + */ + snprintf(ptr, remaining, "snprintf() failed"); + return time_string_buf; } + if ((unsigned int)num_bytes >= remaining) { + /* + * That filled up or would have overflowed the buffer. + * Nothing more we can do. + */ + return time_string_buf; + } + ptr += num_bytes; + remaining -= num_bytes; + + if (tsprecision != 0) { + /* + * Append the fractional part. + */ + num_bytes = format_fractional_part_nsecs(ptr, remaining, timer->nsecs, decimal_point, tsprecision); + if ((unsigned int)num_bytes >= remaining) { + /* + * That filled up or would have overflowed the buffer. + * Nothing more we can do. + */ + return time_string_buf; + } + ptr += num_bytes; + remaining -= num_bytes; + } + + /* + * Append the units. + */ + snprintf(ptr, remaining, "%s%s", + second, + timer->secs == 1 ? "" : plural); + return time_string_buf; } diff --git a/epan/column-utils.c b/epan/column-utils.c index bb6a09e974..9269fd7236 100644 --- a/epan/column-utils.c +++ b/epan/column-utils.c @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef HAVE_LUA #include @@ -961,15 +962,11 @@ col_has_time_fmt(column_info *cinfo, const gint col) (col_item->fmt_matx[COL_DELTA_TIME_DIS])); } -static void -set_abs_ymd_time(const frame_data *fd, gchar *buf, char *decimal_point, gboolean local) +static int +get_frame_timestamp_precision(const frame_data *fd) { int tsprecision; - if (!fd->has_ts) { - buf[0] = '\0'; - return; - } tsprecision = timestamp_get_precision(); if (tsprecision == TS_PREC_AUTO) tsprecision = fd->tsprec; @@ -977,7 +974,32 @@ set_abs_ymd_time(const frame_data *fd, gchar *buf, char *decimal_point, gboolean ws_assert_not_reached(); if (tsprecision > 9) tsprecision = 9; - format_nstime_as_iso8601(buf, COL_MAX_LEN, &fd->abs_ts, decimal_point, local, tsprecision); + return tsprecision; +} + +static int +get_default_timestamp_precision(void) +{ + int tsprecision; + + tsprecision = timestamp_get_precision(); + if (tsprecision == TS_PREC_AUTO) + tsprecision = 9; + else if (tsprecision < 0) + ws_assert_not_reached(); + if (tsprecision > 9) + tsprecision = 9; + return tsprecision; +} + +static void +set_abs_ymd_time(const frame_data *fd, gchar *buf, char *decimal_point, gboolean local) +{ + if (!fd->has_ts) { + buf[0] = '\0'; + return; + } + format_nstime_as_iso8601(buf, COL_MAX_LEN, &fd->abs_ts, decimal_point, local, get_frame_timestamp_precision(fd)); } static void @@ -1003,108 +1025,59 @@ col_set_utc_ymd_time(const frame_data *fd, column_info *cinfo, const int col) static void set_abs_ydoy_time(const frame_data *fd, gchar *buf, char *decimal_point, gboolean local) { - struct tm *tmp; - time_t then; + struct tm tm, *tmp; + char *ptr; + size_t remaining; + int num_bytes; int tsprecision; - if (fd->has_ts) { - then = fd->abs_ts.secs; - if (local) - tmp = localtime(&then); - else - tmp = gmtime(&then); - } else - tmp = NULL; - if (tmp != NULL) { - switch (timestamp_get_precision()) { - case TS_PREC_FIXED_SEC: - tsprecision = WTAP_TSPREC_SEC; - break; - case TS_PREC_FIXED_DSEC: - tsprecision = WTAP_TSPREC_DSEC; - break; - case TS_PREC_FIXED_CSEC: - tsprecision = WTAP_TSPREC_CSEC; - break; - case TS_PREC_FIXED_MSEC: - tsprecision = WTAP_TSPREC_MSEC; - break; - case TS_PREC_FIXED_USEC: - tsprecision = WTAP_TSPREC_USEC; - break; - case TS_PREC_FIXED_NSEC: - tsprecision = WTAP_TSPREC_NSEC; - break; - case TS_PREC_AUTO: - tsprecision = fd->tsprec; - break; - default: - ws_assert_not_reached(); - } - switch (tsprecision) { - case WTAP_TSPREC_SEC: - snprintf(buf, COL_MAX_LEN,"%04d/%03d %02d:%02d:%02d", - tmp->tm_year + 1900, - tmp->tm_yday + 1, - tmp->tm_hour, - tmp->tm_min, - tmp->tm_sec); - break; - case WTAP_TSPREC_DSEC: - snprintf(buf, COL_MAX_LEN,"%04d/%03d %02d:%02d:%02d%s%01d", - tmp->tm_year + 1900, - tmp->tm_yday + 1, - tmp->tm_hour, - tmp->tm_min, - tmp->tm_sec, - decimal_point, - fd->abs_ts.nsecs / 100000000); - break; - case WTAP_TSPREC_CSEC: - snprintf(buf, COL_MAX_LEN,"%04d/%03d %02d:%02d:%02d%s%02d", - tmp->tm_year + 1900, - tmp->tm_yday + 1, - tmp->tm_hour, - tmp->tm_min, - tmp->tm_sec, - decimal_point, - fd->abs_ts.nsecs / 10000000); - break; - case WTAP_TSPREC_MSEC: - snprintf(buf, COL_MAX_LEN, "%04d/%03d %02d:%02d:%02d%s%03d", - tmp->tm_year + 1900, - tmp->tm_yday + 1, - tmp->tm_hour, - tmp->tm_min, - tmp->tm_sec, - decimal_point, - fd->abs_ts.nsecs / 1000000); - break; - case WTAP_TSPREC_USEC: - snprintf(buf, COL_MAX_LEN, "%04d/%03d %02d:%02d:%02d%s%06d", - tmp->tm_year + 1900, - tmp->tm_yday + 1, - tmp->tm_hour, - tmp->tm_min, - tmp->tm_sec, - decimal_point, - fd->abs_ts.nsecs / 1000); - break; - case WTAP_TSPREC_NSEC: - snprintf(buf, COL_MAX_LEN, "%04d/%03d %02d:%02d:%02d%s%09d", - tmp->tm_year + 1900, - tmp->tm_yday + 1, - tmp->tm_hour, - tmp->tm_min, - tmp->tm_sec, - decimal_point, - fd->abs_ts.nsecs); - break; - default: - ws_assert_not_reached(); - } - } else { + if (!fd->has_ts) { buf[0] = '\0'; + return; + } + + if (local) + tmp = ws_localtime_r(&fd->abs_ts.secs, &tm); + else + tmp = ws_gmtime_r(&fd->abs_ts.secs, &tm); + if (tmp == NULL) { + snprintf(buf, COL_MAX_LEN, "Not representable"); + return; + } + ptr = buf; + remaining = COL_MAX_LEN; + num_bytes = snprintf(ptr, remaining,"%04d/%03d %02d:%02d:%02d", + tmp->tm_year + 1900, + tmp->tm_yday + 1, + tmp->tm_hour, + tmp->tm_min, + tmp->tm_sec); + if (num_bytes < 0) { + /* + * That got an error. + * Not much else we can do. + */ + snprintf(ptr, remaining, "snprintf() failed"); + return; + } + if ((unsigned int)num_bytes >= remaining) { + /* + * That filled up or would have overflowed the buffer. + * Nothing more we can do. + */ + return; + } + ptr += num_bytes; + remaining -= num_bytes; + + tsprecision = get_frame_timestamp_precision(fd); + if (tsprecision != 0) { + /* + * Append the fractional part. + * Get the nsecs as a 32-bit unsigned value, as it should never + * be negative, so we treat it as unsigned. + */ + format_fractional_part_nsecs(ptr, remaining, (guint32)fd->abs_ts.nsecs, decimal_point, tsprecision); } } @@ -1131,26 +1104,20 @@ col_set_utc_ydoy_time(const frame_data *fd, column_info *cinfo, const int col) static void set_time_seconds(const frame_data *fd, const nstime_t *ts, gchar *buf) { - int tsprecision; - ws_assert(fd->has_ts); - tsprecision = timestamp_get_precision(); - if (tsprecision == TS_PREC_AUTO) - tsprecision = fd->tsprec; - else if (tsprecision < 0) - ws_assert_not_reached(); - if (tsprecision > 9) - tsprecision = 9; - display_signed_time(buf, COL_MAX_LEN, ts, tsprecision); + display_signed_time(buf, COL_MAX_LEN, ts, get_frame_timestamp_precision(fd)); } static void set_time_hour_min_sec(const frame_data *fd, const nstime_t *ts, gchar *buf, char *decimal_point) { time_t secs = ts->secs; - long nsecs = (long) ts->nsecs; + guint32 nsecs; gboolean negative = FALSE; + char *ptr; + size_t remaining; + int num_bytes; int tsprecision; ws_assert(fd->has_ts); @@ -1159,178 +1126,88 @@ set_time_hour_min_sec(const frame_data *fd, const nstime_t *ts, gchar *buf, char secs = -secs; negative = TRUE; } - if (nsecs < 0) { - nsecs = -nsecs; + if (ts->nsecs >= 0) { + nsecs = ts->nsecs; + } else if (G_LIKELY(ts->nsecs != -2147483648)) { + /* + * This isn't the smallest negative number that fits in 32 + * bits, so we can compute its negative and store it in a + * 32-bit unsigned int variable. + */ + nsecs = -ts->nsecs; + negative = TRUE; + } else { + /* + * -2147483648 is the smallest number that fits in a signed + * 2's complement 32-bit variable, and its negative doesn't + * fit in 32 bits. + * + * Just cast it to a 32-bit unsigned int value to set the + * 32-bit unsigned int variable to 2147483648. + * + * Note that, on platforms where both integers and long + * integers are 32-bit, such as 32-bit UN*Xes and both + * 32-bit *and* 64-bit Windows, making the variable in + * question a long will not avoid undefined behavior. + */ + nsecs = (guint32)ts->nsecs; negative = TRUE; } + ptr = buf; + remaining = COL_MAX_LEN; + if (secs >= (60*60)) { + num_bytes = snprintf(ptr, remaining, "%s%dh %2dm %2d", + negative ? "- " : "", + (gint32) secs / (60 * 60), + (gint32) (secs / 60) % 60, + (gint32) secs % 60); + } else if (secs >= 60) { + num_bytes = snprintf(ptr, remaining, "%s%dm %2d", + negative ? "- " : "", + (gint32) secs / 60, + (gint32) secs % 60); + } else { + num_bytes = snprintf(ptr, remaining, "%s%d", + negative ? "- " : "", + (gint32) secs); + } + if (num_bytes < 0) { + /* + * That got an error. + * Not much else we can do. + */ + snprintf(ptr, remaining, "snprintf() failed"); + return; + } + if ((unsigned int)num_bytes >= remaining) { + /* + * That filled up or would have overflowed the buffer. + * Nothing more we can do. + */ + return; + } + ptr += num_bytes; + remaining -= num_bytes; - switch (timestamp_get_precision()) { - case TS_PREC_FIXED_SEC: - tsprecision = WTAP_TSPREC_SEC; - break; - case TS_PREC_FIXED_DSEC: - tsprecision = WTAP_TSPREC_DSEC; - break; - case TS_PREC_FIXED_CSEC: - tsprecision = WTAP_TSPREC_CSEC; - break; - case TS_PREC_FIXED_MSEC: - tsprecision = WTAP_TSPREC_MSEC; - break; - case TS_PREC_FIXED_USEC: - tsprecision = WTAP_TSPREC_USEC; - break; - case TS_PREC_FIXED_NSEC: - tsprecision = WTAP_TSPREC_NSEC; - break; - case TS_PREC_AUTO: - tsprecision = fd->tsprec; - break; - default: - ws_assert_not_reached(); - } - switch (tsprecision) { - case WTAP_TSPREC_SEC: - if (secs >= (60*60)) { - snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2ds", - negative ? "- " : "", - (gint32) secs / (60 * 60), - (gint32) (secs / 60) % 60, - (gint32) secs % 60); - } else if (secs >= 60) { - snprintf(buf, COL_MAX_LEN, "%s%dm %2ds", - negative ? "- " : "", - (gint32) secs / 60, - (gint32) secs % 60); - } else { - snprintf(buf, COL_MAX_LEN, "%s%ds", - negative ? "- " : "", - (gint32) secs); - } - break; - case WTAP_TSPREC_DSEC: - if (secs >= (60*60)) { - snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d%s%01lds", - negative ? "- " : "", - (gint32) secs / (60 * 60), - (gint32) (secs / 60) % 60, - (gint32) secs % 60, - decimal_point, - nsecs / 100000000); - } else if (secs >= 60) { - snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%01lds", - negative ? "- " : "", - (gint32) secs / 60, - (gint32) secs % 60, - decimal_point, - nsecs / 100000000); - } else { - snprintf(buf, COL_MAX_LEN, "%s%d%s%01lds", - negative ? "- " : "", - (gint32) secs, - decimal_point, - nsecs / 100000000); - } - break; - case WTAP_TSPREC_CSEC: - if (secs >= (60*60)) { - snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d%s%02lds", - negative ? "- " : "", - (gint32) secs / (60 * 60), - (gint32) (secs / 60) % 60, - (gint32) secs % 60, - decimal_point, - nsecs / 10000000); - } else if (secs >= 60) { - snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%02lds", - negative ? "- " : "", - (gint32) secs / 60, - (gint32) secs % 60, - decimal_point, - nsecs / 10000000); - } else { - snprintf(buf, COL_MAX_LEN, "%s%d%s%02lds", - negative ? "- " : "", - (gint32) secs, - decimal_point, - nsecs / 10000000); - } - break; - case WTAP_TSPREC_MSEC: - if (secs >= (60*60)) { - snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d%s%03lds", - negative ? "- " : "", - (gint32) secs / (60 * 60), - (gint32) (secs / 60) % 60, - (gint32) secs % 60, - decimal_point, - nsecs / 1000000); - } else if (secs >= 60) { - snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%03lds", - negative ? "- " : "", - (gint32) secs / 60, - (gint32) secs % 60, - decimal_point, - nsecs / 1000000); - } else { - snprintf(buf, COL_MAX_LEN, "%s%d%s%03lds", - negative ? "- " : "", - (gint32) secs, - decimal_point, - nsecs / 1000000); - } - break; - case WTAP_TSPREC_USEC: - if (secs >= (60*60)) { - snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d%s%06lds", - negative ? "- " : "", - (gint32) secs / (60 * 60), - (gint32) (secs / 60) % 60, - (gint32) secs % 60, - decimal_point, - nsecs / 1000); - } else if (secs >= 60) { - snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%06lds", - negative ? "- " : "", - (gint32) secs / 60, - (gint32) secs % 60, - decimal_point, - nsecs / 1000); - } else { - snprintf(buf, COL_MAX_LEN, "%s%d%s%06lds", - negative ? "- " : "", - (gint32) secs, - decimal_point, - nsecs / 1000); - } - break; - case WTAP_TSPREC_NSEC: - if (secs >= (60*60)) { - snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d%s%09lds", - negative ? "- " : "", - (gint32) secs / (60 * 60), - (gint32) (secs / 60) % 60, - (gint32) secs % 60, - decimal_point, - nsecs); - } else if (secs >= 60) { - snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%09lds", - negative ? "- " : "", - (gint32) secs / 60, - (gint32) secs % 60, - decimal_point, - nsecs); - } else { - snprintf(buf, COL_MAX_LEN, "%s%d%s%09lds", - negative ? "- " : "", - (gint32) secs, - decimal_point, - nsecs); - } - break; - default: - ws_assert_not_reached(); + tsprecision = get_frame_timestamp_precision(fd); + if (tsprecision != 0) { + /* + * Append the fractional part. + */ + num_bytes = format_fractional_part_nsecs(ptr, remaining, nsecs, decimal_point, tsprecision); + if ((unsigned int)num_bytes >= remaining) { + /* + * That filled up or would have overflowed the buffer. + * Nothing more we can do. + */ + return; + } + ptr += num_bytes; + remaining -= num_bytes; } + + /* Append the "s" for seconds. */ + snprintf(ptr, remaining, "s"); } static void @@ -1422,100 +1299,66 @@ col_set_delta_time_dis(const frame_data *fd, column_info *cinfo, const int col) cinfo->columns[col].col_data = cinfo->columns[col].col_buf; } +/* + * Time, without date. + */ static void set_abs_time(const frame_data *fd, gchar *buf, char *decimal_point, gboolean local) { - struct tm *tmp; - time_t then; + struct tm tm, *tmp; + gchar *ptr; + size_t remaining; + int num_bytes; int tsprecision; - if (fd->has_ts) { - then = fd->abs_ts.secs; - if (local) - tmp = localtime(&then); - else - tmp = gmtime(&then); - } else - tmp = NULL; - if (tmp != NULL) { - switch (timestamp_get_precision()) { - case TS_PREC_FIXED_SEC: - tsprecision = WTAP_TSPREC_SEC; - break; - case TS_PREC_FIXED_DSEC: - tsprecision = WTAP_TSPREC_DSEC; - break; - case TS_PREC_FIXED_CSEC: - tsprecision = WTAP_TSPREC_CSEC; - break; - case TS_PREC_FIXED_MSEC: - tsprecision = WTAP_TSPREC_MSEC; - break; - case TS_PREC_FIXED_USEC: - tsprecision = WTAP_TSPREC_USEC; - break; - case TS_PREC_FIXED_NSEC: - tsprecision = WTAP_TSPREC_NSEC; - break; - case TS_PREC_AUTO: - tsprecision = fd->tsprec; - break; - default: - ws_assert_not_reached(); - } - switch (tsprecision) { - case WTAP_TSPREC_SEC: - snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d", - tmp->tm_hour, - tmp->tm_min, - tmp->tm_sec); - break; - case WTAP_TSPREC_DSEC: - snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d%s%01d", - tmp->tm_hour, - tmp->tm_min, - tmp->tm_sec, - decimal_point, - fd->abs_ts.nsecs / 100000000); - break; - case WTAP_TSPREC_CSEC: - snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d%s%02d", - tmp->tm_hour, - tmp->tm_min, - tmp->tm_sec, - decimal_point, - fd->abs_ts.nsecs / 10000000); - break; - case WTAP_TSPREC_MSEC: - snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d%s%03d", - tmp->tm_hour, - tmp->tm_min, - tmp->tm_sec, - decimal_point, - fd->abs_ts.nsecs / 1000000); - break; - case WTAP_TSPREC_USEC: - snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d%s%06d", - tmp->tm_hour, - tmp->tm_min, - tmp->tm_sec, - decimal_point, - fd->abs_ts.nsecs / 1000); - break; - case WTAP_TSPREC_NSEC: - snprintf(buf, COL_MAX_LEN, "%02d:%02d:%02d%s%09d", - tmp->tm_hour, - tmp->tm_min, - tmp->tm_sec, - decimal_point, - fd->abs_ts.nsecs); - break; - default: - ws_assert_not_reached(); - } - - } else { + if (!fd->has_ts) { *buf = '\0'; + return; + } + + ptr = buf; + remaining = COL_MAX_LEN; + + if (local) + tmp = ws_localtime_r(&fd->abs_ts.secs, &tm); + else + tmp = ws_gmtime_r(&fd->abs_ts.secs, &tm); + if (tmp == NULL) { + snprintf(ptr, remaining, "Not representable"); + return; + } + + /* Integral part. */ + num_bytes = snprintf(ptr, remaining, "%02d:%02d:%02d", + tmp->tm_hour, + tmp->tm_min, + tmp->tm_sec); + if (num_bytes < 0) { + /* + * That got an error. + * Not much else we can do. + */ + snprintf(ptr, remaining, "snprintf() failed"); + return; + } + if ((unsigned int)num_bytes >= remaining) { + /* + * That filled up or would have overflowed the buffer. + * Nothing more we can do. + */ + return; + } + ptr += num_bytes; + remaining -= num_bytes; + + tsprecision = get_frame_timestamp_precision(fd); + if (tsprecision != 0) { + /* + * Append the fractional part. + * Get the nsecs as a 32-bit unsigned value, as it should never + * be negative, so we treat it as unsigned. + */ + format_fractional_part_nsecs(ptr, remaining, (guint32)fd->abs_ts.nsecs, decimal_point, tsprecision); } } @@ -1542,20 +1385,11 @@ col_set_utc_time(const frame_data *fd, column_info *cinfo, const int col) static gboolean set_epoch_time(const frame_data *fd, gchar *buf) { - int tsprecision; - if (!fd->has_ts) { buf[0] = '\0'; return FALSE; } - tsprecision = timestamp_get_precision(); - if (tsprecision == TS_PREC_AUTO) - tsprecision = fd->tsprec; - else if (tsprecision < 0) - ws_assert_not_reached(); - if (tsprecision > 9) - tsprecision = 9; - display_epoch_time(buf, COL_MAX_LEN, &fd->abs_ts, tsprecision); + display_epoch_time(buf, COL_MAX_LEN, &fd->abs_ts, get_frame_timestamp_precision(fd)); return TRUE; } @@ -1803,15 +1637,7 @@ col_set_time(column_info *cinfo, const gint el, const nstime_t *ts, const char * for (col = cinfo->col_first[el]; col <= cinfo->col_last[el]; col++) { col_item = &cinfo->columns[col]; if (col_item->fmt_matx[el]) { - int tsprecision = timestamp_get_precision(); - - if (tsprecision == TS_PREC_AUTO) - tsprecision = 9; /* default to maximum */ - else if (tsprecision < 0) - ws_assert_not_reached(); - if (tsprecision > 9) - tsprecision = 9; - display_signed_time(col_item->col_buf, COL_MAX_LEN, ts, tsprecision); + display_signed_time(col_item->col_buf, COL_MAX_LEN, ts, get_default_timestamp_precision()); col_item->col_data = col_item->col_buf; cinfo->col_expr.col_expr[col] = fieldname; (void) g_strlcpy(cinfo->col_expr.col_expr_val[col],col_item->col_buf,COL_MAX_LEN);