mirror of
https://github.com/tio/tio.git
synced 2026-05-01 14:57:59 +02:00
Add hexN output mode
Adds support for hexN mode where N is a number in the range 1 to 4096 which defines how many hex values will be printed before a line break. In short, it defines the width of the hex output. In this mode, if timestamps are enabled they will be added to each hex line.
This commit is contained in:
parent
4113a072c2
commit
42ff234204
5 changed files with 151 additions and 22 deletions
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <regex.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
|
@ -41,6 +42,8 @@
|
|||
#include "log.h"
|
||||
#include "script.h"
|
||||
|
||||
#define HEX_N_VALUE_MAX 4096
|
||||
|
||||
enum opt_t
|
||||
{
|
||||
OPT_NONE,
|
||||
|
|
@ -114,6 +117,7 @@ struct option_t option =
|
|||
.exclude_devices = NULL,
|
||||
.exclude_drivers = NULL,
|
||||
.exclude_tids = NULL,
|
||||
.hex_n_value = 0,
|
||||
};
|
||||
|
||||
void print_help(char *argv[])
|
||||
|
|
@ -140,7 +144,7 @@ void print_help(char *argv[])
|
|||
printf(" -n, --no-reconnect Do not reconnect\n");
|
||||
printf(" -e, --local-echo Enable local echo\n");
|
||||
printf(" --input-mode normal|hex|line Select input mode (default: normal)\n");
|
||||
printf(" --output-mode normal|hex Select output mode (default: normal)\n");
|
||||
printf(" --output-mode normal|hex|hexN Select output mode (default: normal, N <= %d)\n", HEX_N_VALUE_MAX);
|
||||
printf(" -t, --timestamp Enable line timestamp\n");
|
||||
printf(" --timestamp-format <format> Set timestamp format (default: 24hour)\n");
|
||||
printf(" --timestamp-timeout <ms> Set timestamp timeout (default: 200)\n");
|
||||
|
|
@ -268,6 +272,61 @@ void line_pulse_duration_option_parse(const char *arg)
|
|||
free(buffer);
|
||||
}
|
||||
|
||||
// Function to parse the input string
|
||||
int parse_hexN_string(const char *input_string)
|
||||
{
|
||||
regmatch_t match[2]; // One for entire match, one for the optional N
|
||||
int n_value = 0;
|
||||
regex_t regex;
|
||||
int ret;
|
||||
|
||||
// Compile the regular expression to match "hex" and optionally capture N
|
||||
ret = regcomp(®ex, "^hex([0-9]+)?$", REG_EXTENDED);
|
||||
if (ret)
|
||||
{
|
||||
tio_error_printf("Could not compile regex\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Execute the regular expression
|
||||
ret = regexec(®ex, input_string, 2, match, 0);
|
||||
if (!ret)
|
||||
{
|
||||
// If there is a match, extract the N value if present
|
||||
if (match[1].rm_so != -1)
|
||||
{
|
||||
char n_value_str[32]; // Assume max 32 digits for the numerical value
|
||||
strncpy(n_value_str, input_string + match[1].rm_so, match[1].rm_eo - match[1].rm_so);
|
||||
n_value_str[match[1].rm_eo - match[1].rm_so] = '\0'; // Null-terminate the string
|
||||
n_value = atoi(n_value_str);
|
||||
|
||||
if ((n_value > HEX_N_VALUE_MAX) || (n_value == 0))
|
||||
{
|
||||
n_value = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
n_value = 0;
|
||||
}
|
||||
}
|
||||
else if (ret == REG_NOMATCH)
|
||||
{
|
||||
n_value = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char msgbuf[100];
|
||||
regerror(ret, ®ex, msgbuf, sizeof(msgbuf));
|
||||
tio_error_printf("Regex match failed: %s\n", msgbuf);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
regfree(®ex);
|
||||
|
||||
return n_value;
|
||||
}
|
||||
|
||||
input_mode_t input_mode_option_parse(const char *arg)
|
||||
{
|
||||
if (strcmp("normal", arg) == 0)
|
||||
|
|
@ -291,12 +350,15 @@ input_mode_t input_mode_option_parse(const char *arg)
|
|||
|
||||
output_mode_t output_mode_option_parse(const char *arg)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
if (strcmp("normal", arg) == 0)
|
||||
{
|
||||
return OUTPUT_MODE_NORMAL;
|
||||
}
|
||||
else if (strcmp("hex", arg) == 0)
|
||||
else if ((n = parse_hexN_string(arg)) != -1)
|
||||
{
|
||||
option.hex_n_value = n;
|
||||
return OUTPUT_MODE_HEX;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ struct option_t
|
|||
const char *exclude_devices;
|
||||
const char *exclude_drivers;
|
||||
const char *exclude_tids;
|
||||
int hex_n_value;
|
||||
};
|
||||
|
||||
extern struct option_t option;
|
||||
|
|
|
|||
95
src/tty.c
95
src/tty.c
|
|
@ -2086,7 +2086,7 @@ int tty_connect(void)
|
|||
char line_buffer[BUFSIZ] = {};
|
||||
static bool first = true;
|
||||
int status;
|
||||
bool next_timestamp = false;
|
||||
bool do_timestamp = false;
|
||||
char* now = NULL;
|
||||
unsigned int line_index = 0;
|
||||
static char previous_char[2] = {};
|
||||
|
|
@ -2128,7 +2128,7 @@ int tty_connect(void)
|
|||
|
||||
if (option.timestamp)
|
||||
{
|
||||
next_timestamp = true;
|
||||
do_timestamp = true;
|
||||
}
|
||||
|
||||
/* Manage print output mode */
|
||||
|
|
@ -2260,7 +2260,7 @@ int tty_connect(void)
|
|||
rx_total += bytes_read;
|
||||
|
||||
// Manage timeout based timestamping in hex mode
|
||||
if (option.output_mode == OUTPUT_MODE_HEX)
|
||||
if ((option.output_mode == OUTPUT_MODE_HEX) && (option.hex_n_value == 0))
|
||||
{
|
||||
if (option.timestamp != TIMESTAMP_NONE)
|
||||
{
|
||||
|
|
@ -2276,7 +2276,7 @@ int tty_connect(void)
|
|||
{
|
||||
log_printf("\r\n[%s] ", now);
|
||||
}
|
||||
next_timestamp = false;
|
||||
do_timestamp = false;
|
||||
}
|
||||
}
|
||||
tval_before = tval_now;
|
||||
|
|
@ -2286,24 +2286,85 @@ int tty_connect(void)
|
|||
/* Process input byte by byte */
|
||||
for (int i=0; i<bytes_read; i++)
|
||||
{
|
||||
static unsigned long count = 0;
|
||||
|
||||
input_char = input_buffer[i];
|
||||
|
||||
/* Print timestamp on new line if enabled */
|
||||
if (option.output_mode == OUTPUT_MODE_NORMAL)
|
||||
/* Handle timestamps */
|
||||
switch (option.output_mode)
|
||||
{
|
||||
if ((next_timestamp && input_char != '\n' && input_char != '\r'))
|
||||
{
|
||||
now = timestamp_current_time();
|
||||
if (now)
|
||||
case OUTPUT_MODE_NORMAL:
|
||||
// Support timestamp per line
|
||||
if ((do_timestamp && input_char != '\n' && input_char != '\r'))
|
||||
{
|
||||
ansi_printf_raw("[%s] ", now);
|
||||
if (option.log)
|
||||
now = timestamp_current_time();
|
||||
if (now)
|
||||
{
|
||||
log_printf("[%s] ", now);
|
||||
ansi_printf_raw("[%s] ", now);
|
||||
if (option.log)
|
||||
{
|
||||
log_printf("[%s] ", now);
|
||||
}
|
||||
do_timestamp = false;
|
||||
}
|
||||
next_timestamp = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OUTPUT_MODE_HEX:
|
||||
// Support hexN mode
|
||||
if (option.hex_n_value > 0)
|
||||
{
|
||||
static bool first = true;
|
||||
if ((count % option.hex_n_value) == 0)
|
||||
{
|
||||
if (option.timestamp != TIMESTAMP_NONE)
|
||||
{
|
||||
now = timestamp_current_time();
|
||||
if (first)
|
||||
{
|
||||
ansi_printf_raw("[%s] ", now);
|
||||
if (option.log)
|
||||
{
|
||||
log_printf("[%s] ", now);
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ansi_printf_raw("\r\n[%s] ", now);
|
||||
if (option.log)
|
||||
{
|
||||
log_printf("\n[%s] ", now);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
putchar('\r');
|
||||
putchar('\n');
|
||||
|
||||
if (option.log)
|
||||
{
|
||||
log_putc('\n');
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
count++;
|
||||
break;
|
||||
|
||||
default:
|
||||
tio_error_printf("Unknown outut mode");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Convert MSB to LSB bit order */
|
||||
|
|
@ -2324,7 +2385,7 @@ int tty_connect(void)
|
|||
print('\n');
|
||||
if (option.timestamp)
|
||||
{
|
||||
next_timestamp = true;
|
||||
do_timestamp = true;
|
||||
}
|
||||
}
|
||||
else if ((input_char == '\f') && (map_i_ff_escc) && (!map_o_msblsb))
|
||||
|
|
@ -2350,7 +2411,7 @@ int tty_connect(void)
|
|||
|
||||
if (input_char == '\n' && option.timestamp)
|
||||
{
|
||||
next_timestamp = true;
|
||||
do_timestamp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue