mirror of
https://github.com/tio/tio.git
synced 2026-05-01 14:57:59 +02:00
Introduce basic line input mode
This commit is contained in:
parent
d60363a64c
commit
4801816357
8 changed files with 135 additions and 17 deletions
|
|
@ -90,7 +90,7 @@ Options:
|
|||
--line-pulse-duration <duration> Set line pulse duration
|
||||
-n, --no-autoconnect Disable automatic connect
|
||||
-e, --local-echo Enable local echo
|
||||
--input-mode normal|hex Select input mode (default: normal)
|
||||
--input-mode normal|hex|line Select input mode (default: normal)
|
||||
--output-mode normal|hex Select output mode (default: normal)
|
||||
-t, --timestamp Enable line timestamp
|
||||
--timestamp-format <format> Set timestamp format (default: 24hour)
|
||||
|
|
|
|||
7
TODO
7
TODO
|
|
@ -26,10 +26,11 @@
|
|||
|
||||
Time is in ms.
|
||||
|
||||
* Line mode feature
|
||||
* Advanced line mode
|
||||
|
||||
Only send line when pressing enter. Maybe even add readline support so one
|
||||
can use all the readline editing feature before sending the line.
|
||||
Current line mode only support backspace editing. Would be nice with arrow
|
||||
key navigation left/right and insert/overwrite support. Also history browsing
|
||||
pressing up/down.
|
||||
|
||||
* Support for interaction using simple autoresponse strings
|
||||
|
||||
|
|
|
|||
15
man/tio.1.in
15
man/tio.1.in
|
|
@ -191,11 +191,18 @@ If defining more than one flag, the flags must be comma separated.
|
|||
.RE
|
||||
|
||||
.TP
|
||||
.BR " \-\-input\-mode " normal|hex
|
||||
.BR " \-\-input\-mode " normal|hex|line
|
||||
|
||||
Set input mode. In hex input mode bytes can be sent by typing the
|
||||
\fBtwo-character hexadecimal\fR representation of the 1 byte value, e.g.: to
|
||||
send \fI0xA\fR you must type \fI0a\fR or \fI0A\fR.
|
||||
Set input mode.
|
||||
|
||||
In normal mode input characters are sent immediately as they are typed.
|
||||
|
||||
In hex input mode bytes can be sent by typing the \fBtwo-character
|
||||
hexadecimal\fR representation of the 1 byte value, e.g.: to send \fI0xA\fR you
|
||||
must type \fI0a\fR or \fI0A\fR.
|
||||
|
||||
In line input mode input characters are sent when you press enter. The only
|
||||
editing feature supported in this mode is backspace.
|
||||
|
||||
Default value is "normal".
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ typedef enum
|
|||
{
|
||||
INPUT_MODE_NORMAL,
|
||||
INPUT_MODE_HEX,
|
||||
INPUT_MODE_LINE,
|
||||
INPUT_MODE_END,
|
||||
} input_mode_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
109
src/tty.c
109
src/tty.c
|
|
@ -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,13 +1811,108 @@ int tty_connect(void)
|
|||
/* Handle commands */
|
||||
handle_command_sequence(input_char, &output_char, &forward);
|
||||
|
||||
if ((option.input_mode == INPUT_MODE_HEX) && (forward))
|
||||
if (forward)
|
||||
{
|
||||
switch (option.input_mode)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue