/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2004, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2005, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
/*VARARGS*/
void
-pr(s_char *format, ...)
+pr(char *format, ...)
{
- s_char buf[4096];
+ char buf[4096];
va_list ap;
va_start(ap, format);
(void)vsprintf(buf, format, ap);
va_end(ap);
- pr_player(player, C_DATA, buf);
+ if (player->flags & PF_UTF8)
+ upr_player(player, C_DATA, buf);
+ else
+ pr_player(player, C_DATA, buf);
}
void
-prnf(s_char *buf)
+uprnf(char *buf /* buf is message text */)
{
+ if (!(player->flags & PF_UTF8))
+ copy_utf8_to_ascii_no_funny(buf, buf);
+
pr_player(player, C_DATA, buf);
}
}
void
-pr_flash(struct player *pl, s_char *format, ...)
+pr_flash(struct player *pl, char *format
+ /* format is message text */, ...)
{
- s_char buf[4096];
+ char buf[4096]; /* buf is message text */
va_list ap;
if (pl->state != PS_PLAYING)
va_start(ap, format);
(void)vsprintf(buf, format, ap);
va_end(ap);
+ if (!(pl->flags & PF_UTF8))
+ copy_utf8_to_ascii_no_funny(buf, buf);
pr_player(pl, C_FLASH, buf);
io_output(pl->iop, IO_NOWAIT);
}
io_puts(pl->iop, "\n");
pl->curid = -1;
}
- if (pl->curid == -1) {
+ if (pl->curid == -1)
outid(pl, id);
- }
p = strchr(bp, '\n');
if (p != 0) {
len = (p - bp) + 1;
}
}
+void
+upr_player(struct player *pl, int id, char *buf
+ /* buf is message text */)
+{
+ 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 ((ch = *bp++)) {
+ if (pl->curid != -1 && pl->curid != id) {
+ io_puts(pl->iop, "\n");
+ pl->curid = -1;
+ }
+ if (pl->curid == -1)
+ outid(pl, id);
+
+ if (ch & 0x80) {
+ if (standout == 0) {
+ printbuf[0] = 0x0e;
+ io_puts(pl->iop, printbuf);
+ standout = 1;
+ }
+ ch &= 0x7f;
+ } else {
+ if (standout == 1) {
+ printbuf[0] = 0x0f;
+ io_puts(pl->iop, printbuf);
+ standout = 0;
+ }
+ }
+ if (ch == '\n') {
+ if (pl->command && (pl->command->c_flags & C_MOD))
+ io_write(pl->iop, &ch, 1, IO_NOWAIT);
+ else
+ io_write(pl->iop, &ch, 1, IO_WAIT);
+ pl->curid = -1;
+ } else {
+ printbuf[0] = ch;
+ io_puts(pl->iop, printbuf);
+ }
+ }
+}
+
/*
* highlighted characters have hex 80 or'ed in
* with them to designate their highlightedness
register s_char c;
s_char *p;
- p = (s_char *)malloc(strlen(buf) + 1);
+ p = malloc(strlen(buf) + 1);
strcpy(p, buf);
for (bp = p; 0 != (c = *bp); bp++)
if (isprint(c))
pr_id(player, C_PROMPT, "%d %d\n", min, btu);
}
-void
-showvers(int vers)
+int
+prmptrd(char *prompt, char *str, int size)
{
- pr_id(player, C_INIT, "%d\n", vers);
+ int r;
+ char *cp;
+
+ pr_id(player, C_FLUSH, "%s\n", prompt);
+ if ((r = recvclient(str, size)) < 0)
+ return r;
+ time(&player->curup);
+ if (*str == 0)
+ return 1;
+ if (player->flags & PF_UTF8)
+ return copy_utf8_to_ascii_no_funny(str, str);
+ return copy_ascii_no_funny(str, str);
}
int
-prmptrd(s_char *prompt, s_char *str, int size)
+uprmptrd(char *prompt, char *str /* str is message text */, int size)
{
int r;
+ char *cp; /* cp is message text */
pr_id(player, C_FLUSH, "%s\n", prompt);
if ((r = recvclient(str, size)) < 0)
time(&player->curup);
if (*str == 0)
return 1;
- return strlen(str);
+ if (player->flags & PF_UTF8)
+ return copy_utf8_no_funny(str, str);
+ return copy_ascii_no_funny(str, str);
}
void
pr_player(player, C_DATA, buf);
}
}
+
+/*
+ * 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 *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;
+}
+
+/*
+ * Return byte-index of the N-th UTF-8 character in UTF-8 string S.
+ * If S doesn't have that many characters, return its length instead.
+ */
+int
+ufindpfx(char *s, int n)
+{
+ int i = 0;
+
+ while (n && s[i])
+ {
+ if ((s[i++] & 0xc0) == 0xc0)
+ while ((s[i] & 0xc0) == 0x80)
+ i++;
+ --n;
+ }
+ return i;
+}