Add support for configurable timestamp format

Also changes default timestamp format from ISO8601 to classic 24-hour
format as this is assumed to be the format that most users would prefer.

And reintroduces strict but optional ISO8601 format.

This feature allows to easily add more timestamp formats in the future.
This commit is contained in:
Martin Lund 2022-02-19 02:12:24 +01:00
parent 47694904cf
commit d8a822a3fb
6 changed files with 94 additions and 27 deletions

View file

@ -69,7 +69,7 @@ _tio()
return 0
;;
-t | --timestamp)
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "24hour 24hour-start iso8601" -- ${cur}) )
return 0
;;
-L | --list-devices)

View file

@ -27,31 +27,59 @@
#include <sys/time.h>
#include "error.h"
#include "print.h"
#include "options.h"
// "YYYY-MM-DD hh:mm:ss.sss" (ISO-8601/RFC3339 format)
#define TIME_STRING_SIZE 24
#define TIME_STRING_SIZE_MAX 24
char * current_time(void)
char *current_time(void)
{
static char time_string[TIME_STRING_SIZE];
struct tm *tmp;
static char time_string[TIME_STRING_SIZE_MAX];
static struct timeval tv_start;
static bool first = true;
struct tm *tm;
struct timeval tv;
gettimeofday(&tv,NULL);
size_t len;
tmp = localtime(&tv.tv_sec);
if (tmp == NULL)
gettimeofday(&tv, NULL);
if (first)
{
error_printf("Retrieving local time failed");
exit(EXIT_FAILURE);
tv_start = tv;
first = false;
}
size_t len = strftime(time_string, sizeof(time_string), "%Y-%m-%d %H:%M:%S", tmp);
if (len) {
len = snprintf(time_string + len, TIME_STRING_SIZE - len, ".%03ld", (long)tv.tv_usec / 1000);
// Add formatted timestap
switch (option.timestamp)
{
case TIMESTAMP_NONE:
case TIMESTAMP_24HOUR:
// "hh:mm:ss.sss" (24 hour format)
tm = localtime(&tv.tv_sec);
len = strftime(time_string, sizeof(time_string), "%H:%M:%S", tm);
break;
case TIMESTAMP_24HOUR_START:
// "hh:mm:ss.sss" (24 hour format relative to start time)
timersub(&tv, &tv_start, &tv);
tv.tv_sec -= 3600; // Why is this needed??
tm = localtime(&tv.tv_sec);
len = strftime(time_string, sizeof(time_string), "%H:%M:%S", tm);
break;
case TIMESTAMP_ISO8601:
// "YYYY-MM-DDThh:mm:ss.sss" (ISO-8601)
tm = localtime(&tv.tv_sec);
len = strftime(time_string, sizeof(time_string), "%Y-%m-%dT%H:%M:%S", tm);
break;
default:
return NULL;
}
return (len < TIME_STRING_SIZE) ? time_string : NULL;
// Append milliseconds to all timestamps
if (len)
{
len = snprintf(time_string + len, TIME_STRING_SIZE_MAX - len, ".%03ld", (long)tv.tv_usec / 1000);
}
return (len < TIME_STRING_SIZE_MAX) ? time_string : NULL;
}
void delay(long ms)

View file

@ -46,7 +46,7 @@ struct option_t option =
.no_autoconnect = false,
.log = false,
.local_echo = false,
.timestamp = false,
.timestamp = TIMESTAMP_NONE,
.list_devices = false,
.log_filename = "",
.map = "",
@ -66,7 +66,7 @@ void print_help(char *argv[])
printf(" -o, --output-delay <ms> Output delay (default: 0)\n");
printf(" -n, --no-autoconnect Disable automatic connect\n");
printf(" -e, --local-echo Enable local echo\n");
printf(" -t, --timestamp Enable line timestamp\n");
printf(" -t, --timestamp[=<format>] Enable timestamp (default: 24hour)\n");
printf(" -L, --list-devices List available serial devices\n");
printf(" -l, --log <filename> Log to file\n");
printf(" -m, --map <flags> Map special characters\n");
@ -118,7 +118,7 @@ void parse_options(int argc, char *argv[])
{"output-delay", required_argument, 0, 'o'},
{"no-autoconnect", no_argument, 0, 'n'},
{"local-echo", no_argument, 0, 'e'},
{"timestamp", no_argument, 0, 't'},
{"timestamp", optional_argument, 0, 't'},
{"list-devices", no_argument, 0, 'L'},
{"log", required_argument, 0, 'l'},
{"map", required_argument, 0, 'm'},
@ -132,7 +132,7 @@ void parse_options(int argc, char *argv[])
int option_index = 0;
/* Parse argument using getopt_long */
c = getopt_long(argc, argv, "b:d:f:s:p:o:netLl:m:c:vh", long_options, &option_index);
c = getopt_long(argc, argv, "b:d:f:s:p:o:net::Ll:m:c:vh", long_options, &option_index);
/* Detect the end of the options */
if (c == -1)
@ -183,7 +183,27 @@ void parse_options(int argc, char *argv[])
break;
case 't':
option.timestamp = true;
option.timestamp = TIMESTAMP_24HOUR; // Default
if (optarg != NULL)
{
if (strcmp(optarg, "24hour") == 0)
{
option.timestamp = TIMESTAMP_24HOUR;
}
else if (strcmp(optarg, "24hour-start") == 0)
{
option.timestamp = TIMESTAMP_24HOUR_START;
}
else if (strcmp(optarg, "iso8601") == 0)
{
option.timestamp = TIMESTAMP_ISO8601;
}
else
{
printf("Error: Unknown timestamp type\n");
exit(EXIT_FAILURE);
}
}
break;
case 'L':

View file

@ -26,6 +26,14 @@
#include <termios.h>
#include <sys/param.h>
enum timestamp_t
{
TIMESTAMP_NONE,
TIMESTAMP_24HOUR,
TIMESTAMP_24HOUR_START,
TIMESTAMP_ISO8601,
};
/* Options */
struct option_t
{
@ -39,7 +47,7 @@ struct option_t
bool no_autoconnect;
bool log;
bool local_echo;
bool timestamp;
enum timestamp_t timestamp;
bool list_devices;
const char *log_filename;
const char *map;