Introduce basic line input mode

This commit is contained in:
Martin Lund 2024-04-16 17:42:34 +02:00
parent d60363a64c
commit 4801816357
8 changed files with 135 additions and 17 deletions

View file

@ -131,7 +131,7 @@ _tio()
return 0
;;
--input-mode)
COMPREPLY=( $(compgen -W "normal hex" -- ${cur}) )
COMPREPLY=( $(compgen -W "normal hex line" -- ${cur}) )
return 0
;;
--output-mode)

View file

@ -126,7 +126,7 @@ void print_help(char *argv[])
printf(" --line-pulse-duration <duration> Set line pulse duration\n");
printf(" -n, --no-autoconnect Disable automatic connect\n");
printf(" -e, --local-echo Enable local echo\n");
printf(" --input-mode normal|hex Select input mode (default: normal)\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(" -t, --timestamp Enable line timestamp\n");
printf(" --timestamp-format <format> Set timestamp format (default: 24hour)\n");
@ -226,6 +226,10 @@ input_mode_t input_mode_option_parse(const char *arg)
{
return INPUT_MODE_HEX;
}
else if (strcmp("line", arg) == 0)
{
return INPUT_MODE_LINE;
}
else
{
tio_error_printf("Invalid input mode option");
@ -258,6 +262,8 @@ const char *input_mode_by_string(input_mode_t mode)
return "normal";
case INPUT_MODE_HEX:
return "hex";
case INPUT_MODE_LINE:
return "line";
case INPUT_MODE_END:
break;
}

View file

@ -34,6 +34,7 @@ typedef enum
{
INPUT_MODE_NORMAL,
INPUT_MODE_HEX,
INPUT_MODE_LINE,
INPUT_MODE_END,
} input_mode_t;

View file

@ -31,11 +31,13 @@ char ansi_format[30];
void print_hex(char c)
{
print_tainted = true;
printf("%02x ", (unsigned char) c);
}
void print_normal(char c)
{
print_tainted = true;
putchar(c);
}

115
src/tty.c
View file

@ -195,8 +195,6 @@ static void optional_local_echo(char c)
{
log_putc(c);
}
print_tainted_set();
}
inline static bool is_valid_hex(char c)
@ -887,6 +885,11 @@ void handle_command_sequence(char input_char, char *output_char, bool *forward)
tio_printf("Switched to hex input mode");
break;
case INPUT_MODE_LINE:
option.input_mode = INPUT_MODE_LINE;
tio_printf("Switched to line input mode");
break;
case INPUT_MODE_END:
option.input_mode = INPUT_MODE_NORMAL;
tio_printf("Switched to normal input mode");
@ -1531,11 +1534,14 @@ int tty_connect(void)
fd_set rdfs; /* Read file descriptor set */
int maxfd; /* Maximum file descriptor used */
char input_char, output_char;
char input_buffer[BUFSIZ];
char input_buffer[BUFSIZ] = {};
char line_buffer[BUFSIZ] = {};
static bool first = true;
int status;
bool next_timestamp = false;
char* now = NULL;
unsigned int line_index = 0;
static char previous_char[2] = {};
/* Open tty device */
device_fd = open(option.tty_device, O_RDWR | O_NOCTTY | O_NONBLOCK);
@ -1805,12 +1811,107 @@ int tty_connect(void)
/* Handle commands */
handle_command_sequence(input_char, &output_char, &forward);
if ((option.input_mode == INPUT_MODE_HEX) && (forward))
if (forward)
{
if (!is_valid_hex(input_char))
switch (option.input_mode)
{
tio_warning_printf("Invalid hex character: '%d' (0x%02x)", input_char, input_char);
forward = false;
case INPUT_MODE_HEX:
if (!is_valid_hex(input_char))
{
tio_warning_printf("Invalid hex character: '%d' (0x%02x)", input_char, input_char);
forward = false;
}
break;
case INPUT_MODE_LINE:
switch (input_char)
{
case 27: // Escape
forward = false;
break;
case '[':
if (previous_char[0] == 27)
{
forward = false;
}
break;
case 'A':
case 'B':
case 'C':
case 'D':
if ((previous_char[1] == 27) && (previous_char[0] == '['))
{
// Handle arrow keys
switch (input_char)
{
case 'A': // Up arrow
// Ignore
break;
case 'B': // Down arrow
// Ignore
break;
case 'C': // Right arrow
// Ignore
break;
case 'D': // Left arrow
// Ignore
break;
}
forward = false;
}
break;
case '\b':
case 127: // Backspace
if (line_index)
{
if ((option.output_mode == OUTPUT_MODE_HEX) && (option.local_echo))
{
printf("\b\b\b \b\b\b"); // Destructive backspace
}
else
{
printf("\b \b"); // Destructive backspace
}
line_index--;
}
forward = false;
break;
case 13: // Carriage return
// Write buffered line to tty device
tty_write(device_fd, line_buffer, line_index);
tty_write(device_fd, "\r", 1);
optional_local_echo('\r');
tty_sync(device_fd);
putchar('\r');
putchar('\n');
line_index = 0;
forward = false;
break;
default:
if (line_index < BUFSIZ)
{
line_buffer[line_index++] = input_char;
}
else
{
tio_error_print("Input exceeds maximum line length. Truncating.");
forward = false;
}
}
// Save 2 latest stdin input characters
previous_char[1] = previous_char[0];
previous_char[0] = input_char;
break;
default:
break;
}
}
}