Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commit 9374bfe3 authored by rswindell's avatar rswindell

New @-code to output a UNICODE character. 3 different syntaxes:

@U+<codepoint-in-hex>@ - automatic CP437 fallback char, if available
@U+<codepoint-in-hex|cp437char-in-hex>, specify CP437 fallback char
@U+<codepoint-in-hex!cp437char-in-hex>, specify CP437 fallback char
(used if no automatic fallback mapping is available)
parent 7c9fbc7e
......@@ -36,6 +36,8 @@
#include "sbbs.h"
#include "cmdshell.h"
#include "utf8.h"
#include "unicode.h"
#if defined(_WINSOCKAPI_)
extern WSADATA WSAData;
......@@ -128,7 +130,7 @@ int sbbs_t::show_atcode(const char *instr)
const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen)
{
char* tp;
char* tp = NULL;
uint i;
uint ugrp;
uint usub;
......@@ -139,6 +141,25 @@ const char* sbbs_t::atcode(char* sp, char* str, size_t maxlen)
str[0]=0;
if(strncmp(sp, "U+", 2) == 0) { // UNICODE
enum unicode_codepoint codepoint = (enum unicode_codepoint)strtoul(sp + 2, &tp, 16);
if(tp == NULL || *tp ==0)
outchar(codepoint, unicode_to_cp437(codepoint));
else {
char fallback = (char)strtoul(tp + 1, NULL, 16);
if(*tp == '|')
outchar(codepoint, fallback);
else if(*tp == '!') {
char ch = unicode_to_cp437(codepoint);
if(ch != 0)
fallback = ch;
outchar(codepoint, fallback);
}
else return NULL; // Invalid @-code
}
return nulstr;
}
if(!strcmp(sp,"VER"))
return(VERSION);
......
......@@ -250,7 +250,7 @@ size_t sbbs_t::utf8_to_cp437(const char* str, size_t len)
outchar(*str);
return sizeof(char);
}
uint32_t codepoint = 0;
enum unicode_codepoint codepoint = UNICODE_UNDEFINED;
len = utf8_getc(str, len, &codepoint);
if((int)len < 2) {
lprintf(LOG_NOTICE, "Invalid UTF-8 sequence: %02X (error = %d)", (uchar)*str, (int)len);
......@@ -266,7 +266,7 @@ size_t sbbs_t::utf8_to_cp437(const char* str, size_t len)
char ch = unicode_to_cp437(codepoint);
if(ch)
outchar(ch);
else if(!unicode_is_zerowidth(codepoint)) {
else if(unicode_width(codepoint) > 0) {
outchar(CP437_CHAR_INVERTED_QUESTION_MARK);
char seq[32] = "";
for(size_t i = 0; i < len; i++)
......@@ -301,7 +301,7 @@ int sbbs_t::rputs(const char *str, size_t len)
else if((term&NO_EXASCII) && (ch&0x80))
ch = exascii_to_ascii_char(ch); /* seven bit table */
else if(term&UTF8) {
uint32_t codepoint = cp437_unicode_tbl[(uchar)ch];
enum unicode_codepoint codepoint = cp437_unicode_tbl[(uchar)ch];
if(codepoint != 0)
utf8_putc(utf8, sizeof(utf8) - 1, codepoint);
}
......@@ -451,7 +451,7 @@ int sbbs_t::outchar(char ch)
if((term&NO_EXASCII) && (ch&0x80))
ch = exascii_to_ascii_char(ch); /* seven bit table */
else if(term&UTF8) {
uint32_t codepoint = cp437_unicode_tbl[(uchar)ch];
enum unicode_codepoint codepoint = cp437_unicode_tbl[(uchar)ch];
if(codepoint != 0)
utf8_putc(utf8, sizeof(utf8) - 1, codepoint);
}
......@@ -541,14 +541,7 @@ int sbbs_t::outchar(char ch)
column=0;
break;
default:
column++;
if(column >= cols) { // assume terminal has/will auto-line-wrap
lncntr++;
lbuflen = 0;
tos = 0;
lastlinelen = column;
column = 0;
}
inc_column(1);
if(!lbuflen)
latr=curatr;
if(lbuflen<LINE_BUFSIZE)
......@@ -567,6 +560,34 @@ int sbbs_t::outchar(char ch)
return 0;
}
int sbbs_t::outchar(enum unicode_codepoint codepoint, char cp437_fallback)
{
if(term_supports(UTF8)) {
char str[UTF8_MAX_LEN];
int len = utf8_putc(str, sizeof(str), codepoint);
if(len < 1)
return len;
putcom(str, len);
inc_column(unicode_width(codepoint));
return 0;
}
if(cp437_fallback == 0)
return 0;
return outchar(cp437_fallback);
}
void sbbs_t::inc_column(int count)
{
column += count;
if(column >= cols) { // assume terminal has/will auto-line-wrap
lncntr++;
lbuflen = 0;
tos = 0;
lastlinelen = column;
column = 0;
}
}
void sbbs_t::center(char *instr)
{
char str[256];
......
......@@ -715,6 +715,8 @@ public:
;
void backspace(void); /* Output a destructive backspace via outchar */
int outchar(char ch); /* Output a char - check echo and emu. */
int outchar(enum unicode_codepoint, char cp437_fallback = 0);
void inc_column(int count);
void center(char *str);
void clearline(void);
void cleartoeol(void);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment