[mw-devel] [Git][milliways/mw][master] 2 commits: Rework colour handling with a view to making it more flexible
Alice Mitchell
alice at sucs.org
Thu Mar 28 23:41:41 GMT 2019
Alice Mitchell pushed to branch master at milliways / mw
Commits:
3b97891f by Alice Mitchell at 2019-03-28T22:13:07Z
Rework colour handling with a view to making it more flexible
- - - - -
15a0fb44 by Alice Mitchell at 2019-03-28T23:40:35Z
Add simple ANSI-256 colour sequences with &ff& and &ff:ff& sequences
implements #38
- - - - -
3 changed files:
- src/client/colour.c
- src/client/colour.h
- src/client/main.c
Changes:
=====================================
src/client/colour.c
=====================================
@@ -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)
=====================================
src/client/colour.h
=====================================
@@ -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 */
=====================================
src/client/main.c
=====================================
@@ -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, ¬_in_local);
- i=0;
+ if (olen >= (MAXTEXTLENGTH-20)) {
+ outline[olen]='\0';
+ printline_in_local(outline, &convert_warnings, ¬_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, ¬_in_local);
+ outline[olen++] = '\0';
+ printline_in_local(outline, &convert_warnings, ¬_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];
}
}
}
View it on GitLab: https://projects.sucs.org/milliways/mw/compare/fe4f0419b80c691e821a38623712b7f86d9bcb7c...15a0fb4485dee17929cb033ab49c6322f9a9c729
--
View it on GitLab: https://projects.sucs.org/milliways/mw/compare/fe4f0419b80c691e821a38623712b7f86d9bcb7c...15a0fb4485dee17929cb033ab49c6322f9a9c729
You're receiving this email because of your account on projects.sucs.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sucs.org/pipermail/mw-devel/attachments/20190328/9b58db94/attachment-0001.html>
More information about the mw-devel
mailing list