Add special character map feature

Add a --map option which allows to map special characters, in particular CR and
NL characters which are used in various combinations on varios platforms.
This commit is contained in:
Martin Lund 2017-11-05 20:52:12 +01:00
parent 078bb6213d
commit b2aafd696b
6 changed files with 77 additions and 2 deletions

1
README
View file

@ -30,6 +30,7 @@
-o, --output-delay <ms> Output delay (default: 0)
-n, --no-autoconnect Disable automatic connect
-l, --log <filename> Log to file
-m, --map <flags> Map special characters
-v, --version Display version
-h, --help Display help

View file

@ -55,6 +55,28 @@ option is provided, tio will exit if the device is not present or an established
.BR \-l ", " "\-\-log " \fI<filename>
Log to file.
.TP
.BR \-m ", " "\-\-map " \fI<flags>
Map (replace, translate) special characters on input or output. The following mapping flags are supported:
.RS
.TP 8n
.IP "\fBINLCR"
Translate NL to CR on input.
.IP "\fBIGNCR"
Ignore carriage return on input.
.IP "\fBICRNL"
Translate carriage return to newline on input (unless IGNCR is set).
.IP "\fBONLCR"
Map NL to CR-NL on output.
.IP "\fBOCRNL"
Map CR to NL on output.
.P
If defining more than one flag, the flags must be comma separated.
.RE
.TP
.BR \-v ", " \-\-version

View file

@ -18,6 +18,7 @@ _tio()
-o --output-delay \
-n --no-autoconnect \
-l --log \
-m --map \
-v --version \
-h --help"
@ -56,6 +57,10 @@ _tio()
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
;;
-m | --map)
COMPREPLY=( $(compgen -W "INLCR IGNCR ICRNL ONLCR OCRNL" -- ${cur}) )
return 0
;;
-v | --version)
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0

View file

@ -40,6 +40,7 @@ struct option_t
bool no_autoconnect;
bool log;
const char *log_filename;
const char *map;
};
extern struct option_t option;

View file

@ -25,6 +25,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <getopt.h>
#include <termios.h>
@ -44,7 +45,8 @@ struct option_t option =
0, // No output delay
false, // No autoconnect
false, // No log
"" // Log filename
"", // Log filename
"" // Map string
};
void print_help(char *argv[])
@ -60,6 +62,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(" -l, --log <filename> Log to file\n");
printf(" -m, --map <flags> Map special characters\n");
printf(" -v, --version Display version\n");
printf(" -h, --help Display help\n");
printf("\n");
@ -105,6 +108,7 @@ void parse_options(int argc, char *argv[])
{"output-delay", required_argument, 0, 'o'},
{"no-autoconnect", no_argument, 0, 'n'},
{"log", required_argument, 0, 'l'},
{"map", required_argument, 0, 'm'},
{"version", no_argument, 0, 'v'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0 }
@ -114,7 +118,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:nl:vh", long_options, &option_index);
c = getopt_long(argc, argv, "b:d:f:s:p:o:nl:m:vh", long_options, &option_index);
/* Detect the end of the options */
if (c == -1)
@ -165,6 +169,10 @@ void parse_options(int argc, char *argv[])
option.log_filename = optarg;
break;
case 'm':
option.map = optarg;
break;
case 'v':
printf("tio v%s\n", VERSION);
printf("Copyright (c) 2014-2017 Martin Lund\n");

View file

@ -112,6 +112,8 @@ void handle_command_sequence(char input_char, char previous_char, char *output_c
tio_printf(" Stopbits: %d", option.stopbits);
tio_printf(" Parity: %s", option.parity);
tio_printf(" Output delay: %d", option.output_delay);
if (option.map[0] != 0)
tio_printf(" Map flags: %s", option.map);
if (option.log)
tio_printf(" Log file: %s", option.log_filename);
break;
@ -209,6 +211,9 @@ void stdout_restore(void)
void tty_configure(void)
{
bool token_found = true;
char *token = NULL;
char *buffer;
int status;
speed_t baudrate;
@ -335,6 +340,39 @@ void tty_configure(void)
/* Control characters */
tio.c_cc[VTIME] = 0; // Inter-character timer unused
tio.c_cc[VMIN] = 1; // Blocking read until 1 character received
/* Configure any specified input or output mappings */
buffer = strdup(option.map);
while (token_found == true)
{
if (token == NULL)
token = strtok(buffer,",");
else
token = strtok(NULL, ",");
if (token != NULL)
{
if (strcmp(token,"INLCR") == 0)
tio.c_iflag |= INLCR;
else if (strcmp(token,"IGNCR") == 0)
tio.c_iflag |= IGNCR;
else if (strcmp(token,"ICRNL") == 0)
tio.c_iflag |= ICRNL;
else if (strcmp(token,"ONLCR") == 0)
tio.c_oflag |= ONLCR;
else if (strcmp(token,"OCRNL") == 0)
tio.c_oflag |= OCRNL;
else
{
printf("Error: Unknown mapping flag %s\n", token);
exit(EXIT_FAILURE);
}
}
else
token_found = false;
}
free(buffer);
}
void tty_wait_for_device(void)