Pull out parsing of ^C style strings from the terminal answerback code to
authorjacob <jacob@cda61777-01e9-0310-a592-d414129be87e>
Tue, 19 Apr 2005 18:58:29 +0000 (18:58 +0000)
committerjacob <jacob@cda61777-01e9-0310-a592-d414129be87e>
Tue, 19 Apr 2005 18:58:29 +0000 (18:58 +0000)
its own function, since I'll be wanting it for `terminal-modes'.

git-svn-id: svn://svn.tartarus.org/sgt/putty@5646 cda61777-01e9-0310-a592-d414129be87e

misc.c
misc.h
terminal.c

diff --git a/misc.c b/misc.c
index 17d8f39..1beab5e 100644 (file)
--- 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 7346779..f4363e4 100644 (file)
--- 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, ...);
index cd175ba..dfd9a19 100644 (file)
@@ -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);