diff --git a/README.md b/README.md index 772d25f..d80dd0a 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ The command-line interface is straightforward as reflected in the output from -o, --output-delay Output delay (default: 0) -n, --no-autoconnect Disable automatic connect -e, --local-echo Enable local echo - -t, --timestamp Enable line timestamp + -t, --timestamp[=] Enable timestamp (default: 24hour) -L, --list-devices List available serial devices -l, --log Log to file -m, --map Map special characters @@ -42,7 +42,7 @@ The command-line interface is straightforward as reflected in the output from -v, --version Display version -h, --help Display help - See the man page for list of supported mapping flags. + See the man page for more details. In session, press ctrl-t q to quit. ``` diff --git a/man/tio.1.in b/man/tio.1.in index 7ff3825..c37f225 100644 --- a/man/tio.1.in +++ b/man/tio.1.in @@ -57,9 +57,21 @@ option is provided, tio will exit if the device is not present or an established Enable local echo. .TP -.BR \-t ", " \-\-timestamp +.BR \-t ", " \-\-timestamp[=] -Enable line timestamp. +Enable timestamp. Optionally you can specify any of the following timestamp formats: +.RS +.TP 16n +.IP "\fB24hour" +24-hour format ("hh:mm:ss.sss") +.IP "\fB24hour-start" +24-hour format relative to start time +.IP "\fBiso8601" +ISO8601 format ("YYYY-MM-DDThh:mm:ss.sss") +.P +Default format is +.B 24hour +.RE .TP .BR \-L ", " \-\-list\-devices @@ -75,7 +87,6 @@ Log to file. .BR \-m ", " "\-\-map " \fI Map (replace, translate) special characters on input or output. The following mapping flags are supported: - .RS .TP 12n .IP "\fBICRNL" diff --git a/src/bash-completion/tio.in b/src/bash-completion/tio.in index 2457f75..d64d7e3 100644 --- a/src/bash-completion/tio.in +++ b/src/bash-completion/tio.in @@ -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) diff --git a/src/misc.c b/src/misc.c index 0f99024..1a40a0c 100644 --- a/src/misc.c +++ b/src/misc.c @@ -27,31 +27,59 @@ #include #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) diff --git a/src/options.c b/src/options.c index 160faea..ed68437 100644 --- a/src/options.c +++ b/src/options.c @@ -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 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[=] Enable timestamp (default: 24hour)\n"); printf(" -L, --list-devices List available serial devices\n"); printf(" -l, --log Log to file\n"); printf(" -m, --map 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': diff --git a/src/options.h b/src/options.h index 8ff8eea..b03e9f0 100644 --- a/src/options.h +++ b/src/options.h @@ -26,6 +26,14 @@ #include #include +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;