From 3d012d9bd07efebffadcab368c6695f2e295bb21 Mon Sep 17 00:00:00 2001 From: Jacob Nevins Date: Tue, 19 Apr 2005 18:58:29 +0000 Subject: [PATCH] Pull out parsing of ^C style strings from the terminal answerback code to its own function, since I'll be wanting it for `terminal-modes'. [originally from svn r5646] --- misc.c | 36 ++++++++++++++++++++++++++++++++++++ misc.h | 1 + terminal.c | 26 ++++++++++---------------- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/misc.c b/misc.c index 17d8f39b..1beab5e7 100644 --- a/misc.c +++ b/misc.c @@ -43,6 +43,42 @@ unsigned long parse_blocksize(const char *bs) return r; } +/* + * Parse a ^C style character specification. + * Returns NULL in `next' if we didn't recognise it as a control character, + * in which case `c' should be ignored. + * The precise current parsing is an oddity inherited from the terminal + * answerback-string parsing code. All sequences are two characters, + * starting with '^'. The ones that are worth keeping are probably: + * ^? 127 + * ^@A-Z[\]^_ 0-31 + * a-z 1-26 + * ~ ^ escape + */ +char ctrlparse(char *s, char **next) +{ + char c = 0; + if (*s != '^') { + *next = NULL; + return c; + } else { + s++; + if (*s == '\0') { + *next = NULL; + return c; + } else if (*s >= 'a' && *s <= 'z') { + c = (*s - ('a' - 1)); + } else if ((*s >= '@' && *s <= '_') || *s == '?' || (*s & 0x80)) { + c = ('@' ^ *s); + } else if (*s == '~') { + c = '^'; + } + s++; + *next = s; + return c; + } +} + /* ---------------------------------------------------------------------- * String handling routines. */ diff --git a/misc.h b/misc.h index 73467793..f4363e44 100644 --- a/misc.h +++ b/misc.h @@ -18,6 +18,7 @@ typedef struct Filename Filename; typedef struct FontSpec FontSpec; unsigned long parse_blocksize(const char *bs); +char ctrlparse(char *s, char **next); char *dupstr(const char *s); char *dupcat(const char *s1, ...); diff --git a/terminal.c b/terminal.c index cd175ba5..dfd9a19e 100644 --- a/terminal.c +++ b/terminal.c @@ -2677,22 +2677,16 @@ static void term_out(Terminal *term) */ compatibility(ANSIMIN); if (term->ldisc) { - char abuf[256], *s, *d; - int state = 0; - for (s = term->cfg.answerback, d = abuf; *s; s++) { - if (state) { - if (*s >= 'a' && *s <= 'z') - *d++ = (*s - ('a' - 1)); - else if ((*s >= '@' && *s <= '_') || - *s == '?' || (*s & 0x80)) - *d++ = ('@' ^ *s); - else if (*s == '~') - *d++ = '^'; - state = 0; - } else if (*s == '^') { - state = 1; - } else - *d++ = *s; + char abuf[lenof(term->cfg.answerback)], *s, *d; + for (s = term->cfg.answerback, d = abuf; *s;) { + char *n; + char c = ctrlparse(s, &n); + if (n) { + *d++ = c; + s = n; + } else { + *d++ = *s++; + } } lpage_send(term->ldisc, DEFAULT_CODEPAGE, abuf, d - abuf, 0);