]> git.pond.sub.org Git - empserver/blobdiff - src/lib/subs/pr.c
(copy_ascii_no_funny, copy_utf8_no_funny)
[empserver] / src / lib / subs / pr.c
index f6dcd1c9db63e4b1c41a90c2dfd02cebe98b97c4..86fd78755423d46ce7243b83ea56fa08f73b2ed9 100644 (file)
@@ -76,11 +76,8 @@ pr(char *format, ...)
 void
 uprnf(char *buf /* buf is message text */)
 {
-    /*
-     * Translate to ASCII if the client is not in UTF mode
-     */
     if (!(player->flags & PF_UTF8))
-       prtoascii(buf);
+       copy_utf8_to_ascii_no_funny(buf, buf);
 
     pr_player(player, C_DATA, buf);
 }
@@ -114,11 +111,8 @@ pr_flash(struct player *pl, char *format
     va_start(ap, format);
     (void)vsprintf(buf, format, ap);
     va_end(ap);
-    /*
-     * Translate to ASCII if the client is not in UTF mode
-     */
     if (!(pl->flags & PF_UTF8))
-       prtoascii(buf);
+       copy_utf8_to_ascii_no_funny(buf, buf);
     pr_player(pl, C_FLASH, buf);
     io_output(pl->iop, IO_NOWAIT);
 }
@@ -194,12 +188,13 @@ upr_player(struct player *pl, int id, char *buf
     register char *bp; /* bp is message text */
     register int standout = 0;
     char printbuf[2]; /* bp is message text */
+    char ch;
 
     printbuf[0] = '\0';
     printbuf[1] = '\0';
 
     bp = buf;
-    while (*bp != '\0') {
+    while ((ch = *bp++)) {
        if (pl->curid != -1 && pl->curid != id) {
            io_puts(pl->iop, "\n");
            pl->curid = -1;
@@ -207,13 +202,13 @@ upr_player(struct player *pl, int id, char *buf
        if (pl->curid == -1)
            outid(pl, id);
 
-       if (*bp < 0) { /* looking for standout bit 0x80 */
+       if (ch & 0x80) {
            if (standout == 0) {
                printbuf[0] = 0x0e;
                io_puts(pl->iop, printbuf);
                standout = 1;
            }
-           *bp &= 0x7f;
+           ch &= 0x7f;
        } else {
            if (standout == 1) {
                printbuf[0] = 0x0f;
@@ -221,17 +216,16 @@ upr_player(struct player *pl, int id, char *buf
                standout = 0;
            }
        }
-       if (*bp == '\n') {
+       if (ch == '\n') {
            if (pl->command && (pl->command->c_flags & C_MOD))
-               io_write(pl->iop, bp, 1, IO_NOWAIT);
+               io_write(pl->iop, &ch, 1, IO_NOWAIT);
            else
-               io_write(pl->iop, bp, 1, IO_WAIT);
+               io_write(pl->iop, &ch, 1, IO_WAIT);
            pl->curid = -1;
        } else {
-           printbuf[0] = *bp;
+           printbuf[0] = ch;
            io_puts(pl->iop, printbuf);
        }
-        bp++;
     }
 }
 
@@ -297,12 +291,6 @@ prprompt(int min, int btu)
     pr_id(player, C_PROMPT, "%d %d\n", min, btu);
 }
 
-void
-showvers(int vers)
-{
-    pr_id(player, C_INIT, "%d\n", vers);
-}
-
 int
 prmptrd(char *prompt, char *str, int size)
 {
@@ -315,12 +303,9 @@ prmptrd(char *prompt, char *str, int size)
     time(&player->curup);
     if (*str == 0)
        return 1;
-    for(cp = str; 0 != *cp; ++cp) {
-       if ((*cp >= 0x0 && *cp < 0x20 && *cp != '\t') ||
-           *cp == 0x7f || *cp & 0x80)
-           *cp = '?';
-    }
-    return strlen(str);
+    if (player->flags & PF_UTF8)
+       return copy_utf8_to_ascii_no_funny(str, str);
+    return copy_ascii_no_funny(str, str);
 }
 
 int
@@ -335,15 +320,9 @@ uprmptrd(char *prompt, char *str /* str is message text */, int size)
     time(&player->curup);
     if (*str == 0)
        return 1;
-    
-    for(cp = str; 0 != *cp; ++cp) {
-       if ((*cp >= 0x0 && *cp < 0x20 && *cp != '\t') ||
-           *cp == 0x7f)
-           *cp = '?';
-       else if (!(player->flags & PF_UTF8) && (*cp & 0x80))
-           *cp = '?';
-    }
-    return strlen(str);
+    if (player->flags & PF_UTF8)
+       return copy_utf8_no_funny(str, str);
+    return copy_ascii_no_funny(str, str);
 }
 
 void
@@ -428,18 +407,89 @@ mpr(int cn, s_char *format, ...)
     }
 }
 
-void
-prtoascii(char *buf /* buf is message text */)
+/*
+ * Copy SRC without funny characters to DST.
+ * Drop control characters, except for '\t'.
+ * Replace non-ASCII characters by '?'.
+ * Return length of DST.
+ * DST must have space.  If it overlaps SRC, then DST <= SRC must
+ * hold.
+ */
+size_t
+copy_ascii_no_funny(char *dst, char *src)
 {
-    char *pbuf; /* pbuf is message text */
-
-    for(pbuf = buf; *pbuf != 0; pbuf++)
-       if ((*pbuf & 0xc0) == 0xc0)
-           *pbuf = '?';
-       else if (*pbuf & 0x80) {
-           memmove(pbuf,pbuf+1,strlen(pbuf)-1);
-           pbuf--;
-       }
+    char *p;
+    unsigned char ch;
+
+    p = dst;
+    while ((ch = *src++)) {
+       if ((ch < 0x20 && ch != '\t') || ch == 0x7f)
+           ;                   /* ignore control */
+       else if (ch > 0x7f)
+           *p++ = '?'; /* replace non-ASCII */
+       else
+           *p++ = ch;
+    }
+    *p = 0;
+
+    return p - dst;
+}
+
+/*
+ * Copy UTF-8 SRC without funny characters to DST.
+ * Drop control characters, except for '\t'.
+ * FIXME Replace malformed UTF-8 sequences by '?'.
+ * Return byte length of DST.
+ * DST must have space.  If it overlaps SRC, then DST <= SRC must
+ * hold.
+ */
+size_t
+copy_utf8_no_funny(char *dst, char *src)
+{
+    char *p;
+    unsigned char ch;
+
+    p = dst;
+    while ((ch = *src++)) {
+       /* FIXME do the right thing for malformed and overlong sequences */
+       if ((ch < 0x20 && ch != '\t') || ch == 0x7f)
+           ;                   /* ignore control */
+       else
+           *p++ = ch;
+    }
+    *p = 0;
+
+    return p - dst;
+}
+
+/*
+ * Copy UTF-8 SRC without funny characters to ASCII DST.
+ * Drop control characters, except for '\t'.
+ * Replace non-ASCII characters by '?'.
+ * Return length of DST.
+ * DST must have space.  If it overlaps SRC, then DST <= SRC must
+ * hold.
+ */
+size_t
+copy_utf8_to_ascii_no_funny(char *dst, char *src)
+{
+    char *p;
+    unsigned char ch;
+
+    p = dst;
+    while ((ch = *src++)) {
+       /* FIXME do the right thing for malformed and overlong sequences */
+       if ((ch < 0x20 && ch != '\t') || ch == 0x7f)
+           ;                   /* ignore control */
+       else if (ch > 0x7f) {
+           *p++ = '?';         /* replace non-ASCII */
+           while ((*src++ & 0xc0) == 0x80) ;
+       } else
+           *p++ = ch;
+    }
+    *p = 0;
+
+    return p - dst;
 }
 
 /*