Localize decimal point on time formatted columns.

Have the decimal point for sub-second values be locale specific.

Change-Id: I670471e8e5db6291e364d124eb48ddbaa6d8ff26
Ping-Bug: 12500
Reviewed-on: https://code.wireshark.org/review/20621
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Michael Mann 2017-03-19 10:35:04 -04:00 committed by Anders Broman
parent d972ffc25d
commit 1f5c3044f9
1 changed files with 86 additions and 51 deletions

View File

@ -24,6 +24,7 @@
#include <string.h>
#include <time.h>
#include <locale.h>
#include "column-utils.h"
#include "timestamp.h"
@ -49,6 +50,9 @@
#include <epan/wslua/wslua.h>
#endif
/* Used for locale decimal point */
static char *col_decimal_point;
/* Allocate all the data structures for constructing column data, given
the number of columns. */
void
@ -56,6 +60,7 @@ col_setup(column_info *cinfo, const gint num_cols)
{
int i;
col_decimal_point = localeconv()->decimal_point;
cinfo->num_cols = num_cols;
cinfo->columns = g_new(col_item_t, num_cols);
cinfo->col_first = g_new(int, NUM_COL_FMTS);
@ -875,7 +880,7 @@ col_has_time_fmt(column_info *cinfo, const gint col)
}
static void
set_abs_ymd_time(const frame_data *fd, gchar *buf, gboolean local)
set_abs_ymd_time(const frame_data *fd, gchar *buf, char *decimal_point, gboolean local)
{
struct tm *tmp;
time_t then;
@ -926,53 +931,58 @@ set_abs_ymd_time(const frame_data *fd, gchar *buf, gboolean local)
tmp->tm_sec);
break;
case WTAP_TSPREC_DSEC:
ws_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d.%01d",
ws_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d%s%01d",
tmp->tm_year + 1900,
tmp->tm_mon + 1,
tmp->tm_mday,
tmp->tm_hour,
tmp->tm_min,
tmp->tm_sec,
decimal_point,
fd->abs_ts.nsecs / 100000000);
break;
case WTAP_TSPREC_CSEC:
ws_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d.%02d",
ws_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d%s%02d",
tmp->tm_year + 1900,
tmp->tm_mon + 1,
tmp->tm_mday,
tmp->tm_hour,
tmp->tm_min,
tmp->tm_sec,
decimal_point,
fd->abs_ts.nsecs / 10000000);
break;
case WTAP_TSPREC_MSEC:
ws_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
ws_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d%s%03d",
tmp->tm_year + 1900,
tmp->tm_mon + 1,
tmp->tm_mday,
tmp->tm_hour,
tmp->tm_min,
tmp->tm_sec,
decimal_point,
fd->abs_ts.nsecs / 1000000);
break;
case WTAP_TSPREC_USEC:
ws_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d.%06d",
ws_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d%s%06d",
tmp->tm_year + 1900,
tmp->tm_mon + 1,
tmp->tm_mday,
tmp->tm_hour,
tmp->tm_min,
tmp->tm_sec,
decimal_point,
fd->abs_ts.nsecs / 1000);
break;
case WTAP_TSPREC_NSEC:
ws_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d.%09d",
ws_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d%s%09d",
tmp->tm_year + 1900,
tmp->tm_mon + 1,
tmp->tm_mday,
tmp->tm_hour,
tmp->tm_min,
tmp->tm_sec,
decimal_point,
fd->abs_ts.nsecs);
break;
default:
@ -986,7 +996,7 @@ set_abs_ymd_time(const frame_data *fd, gchar *buf, gboolean local)
static void
col_set_abs_ymd_time(const frame_data *fd, column_info *cinfo, const int col)
{
set_abs_ymd_time(fd, cinfo->columns[col].col_buf, TRUE);
set_abs_ymd_time(fd, cinfo->columns[col].col_buf, col_decimal_point, TRUE);
cinfo->col_expr.col_expr[col] = "frame.time";
g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
@ -996,7 +1006,7 @@ col_set_abs_ymd_time(const frame_data *fd, column_info *cinfo, const int col)
static void
col_set_utc_ymd_time(const frame_data *fd, column_info *cinfo, const int col)
{
set_abs_ymd_time(fd, cinfo->columns[col].col_buf, FALSE);
set_abs_ymd_time(fd, cinfo->columns[col].col_buf, col_decimal_point, FALSE);
cinfo->col_expr.col_expr[col] = "frame.time";
g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
@ -1004,7 +1014,7 @@ 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, gboolean local)
set_abs_ydoy_time(const frame_data *fd, gchar *buf, char *decimal_point, gboolean local)
{
struct tm *tmp;
time_t then;
@ -1054,48 +1064,53 @@ set_abs_ydoy_time(const frame_data *fd, gchar *buf, gboolean local)
tmp->tm_sec);
break;
case WTAP_TSPREC_DSEC:
ws_snprintf(buf, COL_MAX_LEN,"%04d/%03d %02d:%02d:%02d.%01d",
ws_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:
ws_snprintf(buf, COL_MAX_LEN,"%04d/%03d %02d:%02d:%02d.%02d",
ws_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:
ws_snprintf(buf, COL_MAX_LEN, "%04d/%03d %02d:%02d:%02d.%03d",
ws_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:
ws_snprintf(buf, COL_MAX_LEN, "%04d/%03d %02d:%02d:%02d.%06d",
ws_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:
ws_snprintf(buf, COL_MAX_LEN, "%04d/%03d %02d:%02d:%02d.%09d",
ws_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:
@ -1109,7 +1124,7 @@ set_abs_ydoy_time(const frame_data *fd, gchar *buf, gboolean local)
static void
col_set_abs_ydoy_time(const frame_data *fd, column_info *cinfo, const int col)
{
set_abs_ydoy_time(fd, cinfo->columns[col].col_buf, TRUE);
set_abs_ydoy_time(fd, cinfo->columns[col].col_buf, col_decimal_point, TRUE);
cinfo->col_expr.col_expr[col] = "frame.time";
g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
@ -1119,7 +1134,7 @@ col_set_abs_ydoy_time(const frame_data *fd, column_info *cinfo, const int col)
static void
col_set_utc_ydoy_time(const frame_data *fd, column_info *cinfo, const int col)
{
set_abs_ydoy_time(fd, cinfo->columns[col].col_buf, FALSE);
set_abs_ydoy_time(fd, cinfo->columns[col].col_buf, col_decimal_point, FALSE);
cinfo->col_expr.col_expr[col] = "frame.time";
g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
@ -1187,7 +1202,7 @@ set_time_seconds(const frame_data *fd, const nstime_t *ts, gchar *buf)
}
static void
set_time_hour_min_sec(const frame_data *fd, const nstime_t *ts, gchar *buf)
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;
@ -1249,106 +1264,121 @@ set_time_hour_min_sec(const frame_data *fd, const nstime_t *ts, gchar *buf)
break;
case WTAP_TSPREC_DSEC:
if (secs >= (60*60)) {
ws_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%01lds",
ws_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) {
ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d.%01lds",
ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%01lds",
negative ? "- " : "",
(gint32) secs / 60,
(gint32) secs % 60,
decimal_point,
nsecs / 100000000);
} else {
ws_snprintf(buf, COL_MAX_LEN, "%s%d.%01lds",
ws_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)) {
ws_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%02lds",
ws_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) {
ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d.%02lds",
ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%02lds",
negative ? "- " : "",
(gint32) secs / 60,
(gint32) secs % 60,
decimal_point,
nsecs / 10000000);
} else {
ws_snprintf(buf, COL_MAX_LEN, "%s%d.%02lds",
ws_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)) {
ws_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%03lds",
ws_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) {
ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d.%03lds",
ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%03lds",
negative ? "- " : "",
(gint32) secs / 60,
(gint32) secs % 60,
decimal_point,
nsecs / 1000000);
} else {
ws_snprintf(buf, COL_MAX_LEN, "%s%d.%03lds",
ws_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)) {
ws_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%06lds",
ws_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) {
ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d.%06lds",
ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%06lds",
negative ? "- " : "",
(gint32) secs / 60,
(gint32) secs % 60,
decimal_point,
nsecs / 1000);
} else {
ws_snprintf(buf, COL_MAX_LEN, "%s%d.%06lds",
ws_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)) {
ws_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%09lds",
ws_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) {
ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d.%09lds",
ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%09lds",
negative ? "- " : "",
(gint32) secs / 60,
(gint32) secs % 60,
decimal_point,
nsecs);
} else {
ws_snprintf(buf, COL_MAX_LEN, "%s%d.%09lds",
ws_snprintf(buf, COL_MAX_LEN, "%s%d%s%09lds",
negative ? "- " : "",
(gint32) secs,
decimal_point,
nsecs);
}
break;
@ -1376,7 +1406,7 @@ col_set_rel_time(const frame_data *fd, column_info *cinfo, const int col)
g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
break;
case TS_SECONDS_HOUR_MIN_SEC:
set_time_hour_min_sec(fd, &del_rel_ts, cinfo->columns[col].col_buf);
set_time_hour_min_sec(fd, &del_rel_ts, cinfo->columns[col].col_buf, col_decimal_point);
cinfo->col_expr.col_expr[col] = "frame.time_relative";
set_time_seconds(fd, &del_rel_ts, cinfo->col_expr.col_expr_val[col]);
break;
@ -1400,7 +1430,7 @@ col_set_delta_time(const frame_data *fd, column_info *cinfo, const int col)
g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
break;
case TS_SECONDS_HOUR_MIN_SEC:
set_time_hour_min_sec(fd, &del_cap_ts, cinfo->columns[col].col_buf);
set_time_hour_min_sec(fd, &del_cap_ts, cinfo->columns[col].col_buf, col_decimal_point);
cinfo->col_expr.col_expr[col] = "frame.time_delta";
set_time_seconds(fd, &del_cap_ts, cinfo->col_expr.col_expr_val[col]);
break;
@ -1430,7 +1460,7 @@ col_set_delta_time_dis(const frame_data *fd, column_info *cinfo, const int col)
g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
break;
case TS_SECONDS_HOUR_MIN_SEC:
set_time_hour_min_sec(fd, &del_dis_ts, cinfo->columns[col].col_buf);
set_time_hour_min_sec(fd, &del_dis_ts, cinfo->columns[col].col_buf, col_decimal_point);
cinfo->col_expr.col_expr[col] = "frame.time_delta_displayed";
set_time_seconds(fd, &del_dis_ts, cinfo->col_expr.col_expr_val[col]);
break;
@ -1442,7 +1472,7 @@ col_set_delta_time_dis(const frame_data *fd, column_info *cinfo, const int col)
}
static void
set_abs_time(const frame_data *fd, gchar *buf, gboolean local)
set_abs_time(const frame_data *fd, gchar *buf, char *decimal_point, gboolean local)
{
struct tm *tmp;
time_t then;
@ -1490,38 +1520,43 @@ set_abs_time(const frame_data *fd, gchar *buf, gboolean local)
tmp->tm_sec);
break;
case WTAP_TSPREC_DSEC:
ws_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d.%01d",
ws_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:
ws_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d.%02d",
ws_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:
ws_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d.%03d",
ws_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:
ws_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d.%06d",
ws_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:
ws_snprintf(buf, COL_MAX_LEN, "%02d:%02d:%02d.%09d",
ws_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:
@ -1536,7 +1571,7 @@ set_abs_time(const frame_data *fd, gchar *buf, gboolean local)
static void
col_set_abs_time(const frame_data *fd, column_info *cinfo, const int col)
{
set_abs_time(fd, cinfo->columns[col].col_buf, TRUE);
set_abs_time(fd, cinfo->columns[col].col_buf, col_decimal_point, TRUE);
cinfo->col_expr.col_expr[col] = "frame.time";
g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
@ -1546,7 +1581,7 @@ col_set_abs_time(const frame_data *fd, column_info *cinfo, const int col)
static void
col_set_utc_time(const frame_data *fd, column_info *cinfo, const int col)
{
set_abs_time(fd, cinfo->columns[col].col_buf, FALSE);
set_abs_time(fd, cinfo->columns[col].col_buf, col_decimal_point, FALSE);
cinfo->col_expr.col_expr[col] = "frame.time";
g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
@ -1634,15 +1669,15 @@ set_fd_time(const epan_t *epan, frame_data *fd, gchar *buf)
switch (timestamp_get_type()) {
case TS_ABSOLUTE:
set_abs_time(fd, buf, TRUE);
set_abs_time(fd, buf, col_decimal_point, TRUE);
break;
case TS_ABSOLUTE_WITH_YMD:
set_abs_ymd_time(fd, buf, TRUE);
set_abs_ymd_time(fd, buf, col_decimal_point, TRUE);
break;
case TS_ABSOLUTE_WITH_YDOY:
set_abs_ydoy_time(fd, buf, TRUE);
set_abs_ydoy_time(fd, buf, col_decimal_point, TRUE);
break;
case TS_RELATIVE:
@ -1677,7 +1712,7 @@ set_fd_time(const epan_t *epan, frame_data *fd, gchar *buf)
set_time_seconds(fd, &del_cap_ts, buf);
break;
case TS_SECONDS_HOUR_MIN_SEC:
set_time_hour_min_sec(fd, &del_cap_ts, buf);
set_time_hour_min_sec(fd, &del_cap_ts, buf, col_decimal_point);
break;
default:
g_assert_not_reached();
@ -1698,7 +1733,7 @@ set_fd_time(const epan_t *epan, frame_data *fd, gchar *buf)
set_time_seconds(fd, &del_dis_ts, buf);
break;
case TS_SECONDS_HOUR_MIN_SEC:
set_time_hour_min_sec(fd, &del_dis_ts, buf);
set_time_hour_min_sec(fd, &del_dis_ts, buf, col_decimal_point);
break;
default:
g_assert_not_reached();
@ -1713,15 +1748,15 @@ set_fd_time(const epan_t *epan, frame_data *fd, gchar *buf)
break;
case TS_UTC:
set_abs_time(fd, buf, FALSE);
set_abs_time(fd, buf, col_decimal_point, FALSE);
break;
case TS_UTC_WITH_YMD:
set_abs_ymd_time(fd, buf, FALSE);
set_abs_ymd_time(fd, buf, col_decimal_point, FALSE);
break;
case TS_UTC_WITH_YDOY:
set_abs_ydoy_time(fd, buf, FALSE);
set_abs_ydoy_time(fd, buf, col_decimal_point, FALSE);
break;
case TS_NOT_SET: