Skip to content
Commits on Source (2)
......@@ -22,85 +22,166 @@ static char *colour_set=NULL;
/* the current user template */
extern struct user * const user;
/* return colour code sequence */
char *colour(char *text)
/* safe copy string */
static void copy_in(char *dest, int len, const char *input)
{
static char line[40];
int i;
snprintf(dest, len, "%s", input);
}
line[0]=0;
static int hex_decode(const char *input, int len)
{
int i=0;
int total=0;
/* system colour chart */
if (strchr("0123456789",text[0]))
{
i=atoi(text);
if (i<0 || i>= COLOUR_LIMIT) return(line);
if (colour_chart[i]==NULL)
if (colour_chart[0]==NULL)
return(line);
else
return (colour_chart[0]);
while (i<len && *input) {
total <<= 4;
if (*input >= '0' && *input <= '9')
total |= *input - '0';
else
return (colour_chart[i]);
}
i=0;
line[i++]=033;
line[i++]='[';
/* reset string ? */
if (strchr("-n", text[0]) &&
strchr("-n", text[1]) )
{
line[i++]='m';
line[i]=0;
return(line);
}
/* high intensity mode? */
if (isupper(text[0]))
{
line[i++]='1';
line[i++]=';';
} else {
line[i++]='0';
line[i++]=';';
if (*input >= 'a' && *input <= 'f')
total |= (*input - 'a') + 10;
else
if (*input >= 'A' && *input <= 'F')
total |= (*input - 'a') + 10;
input++;
i++;
}
return total;
}
if (strchr("kKrRgGyYbBmMcCwW", text[0])!=NULL)
{
if (strchr("n-", text[0])==NULL) line[i++]='3';
if (strchr("kK",text[0])) line[i++]='0'; else
if (strchr("rR",text[0])) line[i++]='1'; else
if (strchr("gG",text[0])) line[i++]='2'; else
if (strchr("yY",text[0])) line[i++]='3'; else
if (strchr("bB",text[0])) line[i++]='4'; else
if (strchr("mM",text[0])) line[i++]='5'; else
if (strchr("cC",text[0])) line[i++]='6'; else
if (strchr("wW",text[0])) line[i++]='7';
/* seperator */
if (strchr("n-",text[0])==NULL && strchr("n-",text[1])==NULL) line[i++]=';';
/* return colour code sequence */
int colour(const char *input, char *output, int outlen)
{
int consume = 0;
/* original colour mode */
if (*input == 033) {
char text[3];
int i = 0;
consume = 1;
/* build the string, skipping unicode sequences */
while (i < 2 && input[consume] != 0) {
if ((input[consume] & 192) == 192) {
consume++;
text[i++] = '-';
while ((input[consume] & 192) == 128)
consume++;
} else {
text[i++] = input[consume++];
}
}
text[2] = '\0';
/* system colour chart */
if (strchr("0123456789",text[0]))
{
i=atoi(text);
if (i>=0 && i < COLOUR_LIMIT) {
if (colour_chart[i] != NULL)
copy_in(output, outlen, colour_chart[i]);
else
if (colour_chart[0] != NULL)
copy_in(output, outlen, colour_chart[0]);
}
return consume;
}
i=0;
output[i++] = 033;
output[i++] = '[';
/* reset string ? */
if (strchr("-n", text[0]) &&
strchr("-n", text[1]) )
{
output[i++] = 'm';
output[i] = '\0';
return(consume);
}
/* high intensity mode? */
if (isupper(text[0]))
{
output[i++] = '1';
output[i++] = ';';
} else {
output[i++] = '0';
output[i++] = ';';
}
if (strchr("kKrRgGyYbBmMcCwW", text[0])!=NULL)
{
if (strchr("n-", text[0])==NULL) output[i++] = '3';
if (strchr("kK",text[0])) output[i++] = '0'; else
if (strchr("rR",text[0])) output[i++] = '1'; else
if (strchr("gG",text[0])) output[i++] = '2'; else
if (strchr("yY",text[0])) output[i++] = '3'; else
if (strchr("bB",text[0])) output[i++] = '4'; else
if (strchr("mM",text[0])) output[i++] = '5'; else
if (strchr("cC",text[0])) output[i++] = '6'; else
if (strchr("wW",text[0])) output[i++] = '7';
/* seperator */
if (strchr("n-",text[0])==NULL && strchr("n-",text[1])==NULL)
output[i++] = ';';
}
if (strchr("kKrRgGyYbBmMcCwW", text[1])!=NULL)
{
/* now background colour */
if (strchr("n-",text[1])==NULL) output[i++] = '4';
if (strchr("kK",text[1])) output[i++] = '0'; else
if (strchr("rR",text[1])) output[i++] = '1'; else
if (strchr("gG",text[1])) output[i++] = '2'; else
if (strchr("yY",text[1])) output[i++] = '3'; else
if (strchr("bB",text[1])) output[i++] = '4'; else
if (strchr("mM",text[1])) output[i++] = '5'; else
if (strchr("cC",text[1])) output[i++] = '6'; else
if (strchr("wW",text[1])) output[i++] = '7';
}
output[i++] = 'm';
output[i] = '\0';
}
if (strchr("kKrRgGyYbBmMcCwW", text[1])!=NULL)
{
/* now background colour */
if (strchr("n-",text[1])==NULL) line[i++]='4';
if (strchr("kK",text[1])) line[i++]='0'; else
if (strchr("rR",text[1])) line[i++]='1'; else
if (strchr("gG",text[1])) line[i++]='2'; else
if (strchr("yY",text[1])) line[i++]='3'; else
if (strchr("bB",text[1])) line[i++]='4'; else
if (strchr("mM",text[1])) line[i++]='5'; else
if (strchr("cC",text[1])) line[i++]='6'; else
if (strchr("wW",text[1])) line[i++]='7';
if (*input == '&') {
/* first let us test this is a valid colour string */
const char *p = input + 1;
/* skip past all valid chars */
while (*p && strchr("0123456789AbBcCdDeEfF:", *p)) p++;
/* not the ending we were expecting, ignore it then */
if (*p != '&') return 0;
char hex[7];
int i = 0;
consume = 1;
while (i < 7 && input[consume] && strchr("0123456789AbBcCdDeEfF", input[consume]))
hex[i++] = input[consume++];
hex[i] = '\0';
if (i == 2) {
int col = hex_decode(hex, 2);
snprintf(output, outlen, "\033[38;5;%dm", col);
}
if (input[consume] == ':') {
consume++;
i=0;
while (i < 7 && input[consume] && strchr("0123456789AbBcCdDeEfF", input[consume]))
hex[i++] = input[consume++];
hex[i] = '\0';
if (i == 2) {
int col = hex_decode(hex, 2);
int off = strlen(output);
snprintf(&output[off], outlen-off, "\033[48;5;%dm", col);
}
}
while (input[consume] && strchr("0123456789AbBcCdDeEfF:", input[consume]))
consume++;
if (input[consume] == '&') consume++;
}
line[i++]='m';
line[i]=0;
return(line);
return(consume);
}
void colour_free(void)
......
......@@ -7,7 +7,7 @@ void init_colour(void);
void destroy_colours(void);
void colour_load(char *file, int quiet);
void colour_free(void);
char *colour(char *text);
int colour(const char *input, char *output, int outlen);
char *get_colour(void);
#endif /* COLOUR_H */
......@@ -1070,140 +1070,83 @@ void format_message(const char *format, ...)
void display_message(const char *text, int beeps, int newline)
{
static int count = 0;
char line[MAXTEXTLENGTH];
int i, j, colrstart;
int hascolour;
char outline[MAXTEXTLENGTH];
int olen = 0;
int screen_width = screen_w();
char *colr = NULL;
int endline;
char colr[128];
int convert_warnings=0;
const unsigned char *ptr = (const unsigned char *)text;
const unsigned char *end;
int charcount = 0;
bool endline;
size_t not_in_local = 0;
size_t len;
if (text == NULL || (len = strlen(text)) == 0) {
if (text == NULL || strlen(text) == 0) {
printf("%s", _("Error: Urk, no message to print.\n"));
return;
}
if (UseRL && disable_rl(1)) count = 0;
i=0;
hascolour=0;
colrstart=-1;
end = ptr + len;
while (ptr < end) {
if (*ptr == 033) {
char str[3];
ptr++;
if (ptr < end) {
if ((*ptr & 192) == 192) {
ptr++;
str[0] = '-';
while ((*ptr & 192) == 128 && ptr < end)
ptr++;
} else {
str[0] = *ptr;
ptr++;
}
}
if (ptr < end) {
if((*ptr & 192) == 192) {
ptr++;
str[1] = '-';
while((*ptr & 192) == 128 && ptr < end)
ptr++;
} else {
str[1] = *ptr;
ptr++;
}
}
if (UseRL && disable_rl(1)) charcount = 0;
while (*text) {
if (*text == 033 || *text == '&') {
/* escape sequence, skip next two chars */
if (s_colouroff(user))
goto eolprint;
hascolour++;
str[2] = 0;
colr = colour(str);
text += colour(text, colr, sizeof(colr));
if (colr!=NULL)
{
if (colrstart >= 0)
i = colrstart;
else
colrstart = i;
for (j = 0; j < strlen(colr); j++)
line[i++] = colr[j];
if (colr[0] && !s_colouroff(user)) {
for (int j = 0; j < strlen(colr); j++)
outline[olen++] = colr[j];
}
} else if (*ptr >= 040 && *ptr <= 0176) {
line[i++] = *ptr;
count++;
colrstart = -1;
ptr++;
} else if ((*ptr & 192) == 192) {
line[i++] = *ptr;
count++;
colrstart = -1;
ptr++;
} else if (*text >= 040 && *text <= 0176) {
outline[olen++] = *text++;
charcount++;
} else if ((*text & 192) == 192) {
outline[olen++] = *text++;
// stops us randomly splitting over a unicode multibyte character
while ((*ptr & 192) == 128 && ptr < end) {
line[i++] = *ptr;
colrstart = -1;
ptr++;
while ((*text & 192) == 128 && *text) {
outline[olen++] = *text++;
}
charcount++;
} else {
ptr++;
text++;
}
if (i >= (MAXTEXTLENGTH-20))
{
line[i]='\0';
printline_in_local(line, &convert_warnings, &not_in_local);
i=0;
if (olen >= (MAXTEXTLENGTH-20)) {
outline[olen]='\0';
printline_in_local(outline, &convert_warnings, &not_in_local);
olen=0;
charcount=0;
}
eolprint:
if (s_nolinewrap(user))
endline = (ptr >= end);
endline = (*text == 0);
else
endline = ((count >= screen_width) || (ptr >= end));
endline = ((charcount >= screen_width) || *text==0);
if (endline)
{
if (!s_colouroff(user) && hascolour)
{
line[i++]=033;
line[i++]='[';
line[i++]='m';
if (!s_colouroff(user) && colr[0]) {
outline[olen++] = 033;
outline[olen++] = '[';
outline[olen++] = 'm';
}
if (newline || (ptr < end))
{
line[i++]='\n';
count=0;
if (newline || *text) {
outline[olen++] = '\n';
charcount=0;
}
line[i]='\0';
printline_in_local(line, &convert_warnings, &not_in_local);
outline[olen++] = '\0';
printline_in_local(outline, &convert_warnings, &not_in_local);
olen = 0;
if (newline) charcount=0;
if (*text) {
outline[olen++] = ' ';
charcount = 1;
if (ptr >= end)
{
i=0;
if (newline) count=0;
} else
{
i=2;
count=2;
strcpy(line," ");
/* Restore the colour from the last line */
if (!s_colouroff(user) &&
hascolour &&
colr!=NULL)
{
for (j=0; j < strlen(colr); j++)
line[i++] = colr[j];
if (!s_colouroff(user) && colr[0]) {
for (int j=0; j < strlen(colr); j++)
outline[olen++] = colr[j];
}
}
}
......