code-golfing: cleanup osc color related code

* adds missing function prototype
* move xgetcolor() prototype to win.h (that's where all the other x.c
  func prototype seems to be declared at)
* check for snprintf error/truncation
* reduces code duplication for osc 10/11/12
* unify osc_color_response() and osc4_color_response() into a single function

the latter two was suggested by Quentin Rameau in his patch review on
the hackers list.
This commit is contained in:
NRK 2022-01-07 23:21:04 +06:00 committed by Hiltjo Posthuma
parent ef0551932f
commit 8629d9a1da
3 changed files with 32 additions and 59 deletions

86
st.c
View file

@ -161,6 +161,7 @@ static void csidump(void);
static void csihandle(void); static void csihandle(void);
static void csiparse(void); static void csiparse(void);
static void csireset(void); static void csireset(void);
static void osc_color_response(int, int, int);
static int eschandle(uchar); static int eschandle(uchar);
static void strdump(void); static void strdump(void);
static void strhandle(void); static void strhandle(void);
@ -1835,39 +1836,28 @@ csireset(void)
} }
void void
osc4_color_response(int num) osc_color_response(int num, int index, int is_osc4)
{ {
int n; int n;
char buf[32]; char buf[32];
unsigned char r, g, b; unsigned char r, g, b;
if (xgetcolor(num, &r, &g, &b)) { if (xgetcolor(is_osc4 ? num : index, &r, &g, &b)) {
fprintf(stderr, "erresc: failed to fetch osc4 color %d\n", num); fprintf(stderr, "erresc: failed to fetch %s color %d\n",
is_osc4 ? "osc4" : "osc",
is_osc4 ? num : index);
return; return;
} }
n = snprintf(buf, sizeof buf, "\033]4;%d;rgb:%02x%02x/%02x%02x/%02x%02x\007", n = snprintf(buf, sizeof buf, "\033]%s%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
num, r, r, g, g, b, b); is_osc4 ? "4;" : "", num, r, r, g, g, b, b);
if (n < 0 || n >= sizeof(buf)) {
fprintf(stderr, "error: %s while printing %s response\n",
n < 0 ? "snprintf failed" : "truncation occurred",
is_osc4 ? "osc4" : "osc");
} else {
ttywrite(buf, n, 1); ttywrite(buf, n, 1);
} }
void
osc_color_response(int index, int num)
{
int n;
char buf[32];
unsigned char r, g, b;
if (xgetcolor(index, &r, &g, &b)) {
fprintf(stderr, "erresc: failed to fetch osc color %d\n", index);
return;
}
n = snprintf(buf, sizeof buf, "\033]%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
num, r, r, g, g, b, b);
ttywrite(buf, n, 1);
} }
void void
@ -1875,6 +1865,11 @@ strhandle(void)
{ {
char *p = NULL, *dec; char *p = NULL, *dec;
int j, narg, par; int j, narg, par;
const struct { int idx; char *str; } osc_table[] = {
{ defaultfg, "foreground" },
{ defaultbg, "background" },
{ defaultcs, "cursor" }
};
term.esc &= ~(ESC_STR_END|ESC_STR); term.esc &= ~(ESC_STR_END|ESC_STR);
strparse(); strparse();
@ -1909,43 +1904,22 @@ strhandle(void)
} }
return; return;
case 10: case 10:
if (narg < 2)
break;
p = strescseq.args[1];
if (!strcmp(p, "?"))
osc_color_response(defaultfg, 10);
else if (xsetcolorname(defaultfg, p))
fprintf(stderr, "erresc: invalid foreground color: %s\n", p);
else
tfulldirt();
return;
case 11: case 11:
if (narg < 2)
break;
p = strescseq.args[1];
if (!strcmp(p, "?"))
osc_color_response(defaultbg, 11);
else if (xsetcolorname(defaultbg, p))
fprintf(stderr, "erresc: invalid background color: %s\n", p);
else
tfulldirt();
return;
case 12: case 12:
if (narg < 2) if (narg < 2)
break; break;
p = strescseq.args[1]; p = strescseq.args[1];
if ((j = par - 10) < 0 || j >= LEN(osc_table))
break; /* shouldn't be possible */
if (!strcmp(p, "?")) if (!strcmp(p, "?")) {
osc_color_response(defaultcs, 12); osc_color_response(par, osc_table[j].idx, 0);
else if (xsetcolorname(defaultcs, p)) } else if (xsetcolorname(osc_table[j].idx, p)) {
fprintf(stderr, "erresc: invalid cursor color: %s\n", p); fprintf(stderr, "erresc: invalid %s color: %s\n",
else osc_table[j].str, p);
} else {
tfulldirt(); tfulldirt();
}
return; return;
case 4: /* color set */ case 4: /* color set */
if (narg < 3) if (narg < 3)
@ -1955,9 +1929,9 @@ strhandle(void)
case 104: /* color reset */ case 104: /* color reset */
j = (narg > 1) ? atoi(strescseq.args[1]) : -1; j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
if (p && !strcmp(p, "?")) if (p && !strcmp(p, "?")) {
osc4_color_response(j); osc_color_response(j, 0, 1);
else if (xsetcolorname(j, p)) { } else if (xsetcolorname(j, p)) {
if (par == 104 && narg <= 1) if (par == 104 && narg <= 1)
return; /* color reset without parameter */ return; /* color reset without parameter */
fprintf(stderr, "erresc: invalid color j=%d, p=%s\n", fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",

2
st.h
View file

@ -111,8 +111,6 @@ void *xmalloc(size_t);
void *xrealloc(void *, size_t); void *xrealloc(void *, size_t);
char *xstrdup(const char *); char *xstrdup(const char *);
int xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b);
/* config.h globals */ /* config.h globals */
extern char *utmp; extern char *utmp;
extern char *scroll; extern char *scroll;

1
win.h
View file

@ -30,6 +30,7 @@ void xdrawline(Line, int, int, int);
void xfinishdraw(void); void xfinishdraw(void);
void xloadcols(void); void xloadcols(void);
int xsetcolorname(int, const char *); int xsetcolorname(int, const char *);
int xgetcolor(int, unsigned char *, unsigned char *, unsigned char *);
void xseticontitle(char *); void xseticontitle(char *);
void xsettitle(char *); void xsettitle(char *);
int xsetcursor(int); int xsetcursor(int);