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

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)