~petersanchez/st

64c63baf91027a30ba4bbb81a2bffbdaaeb39ca9 — NRK 2 years ago d8ec4d9
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.
3 files changed, 33 insertions(+), 60 deletions(-)

M st.c
M st.h
M win.h
M st.c => st.c +32 -58
@@ 168,6 168,7 @@ static void csidump(void);
static void csihandle(void);
static void csiparse(void);
static void csireset(void);
static void osc_color_response(int, int, int);
static int eschandle(uchar);
static void strdump(void);
static void strhandle(void);


@@ 1897,39 1898,28 @@ csireset(void)
}

void
osc4_color_response(int num)
osc_color_response(int num, int index, int is_osc4)
{
	int n;
	char buf[32];
	unsigned char r, g, b;

	if (xgetcolor(num, &r, &g, &b)) {
		fprintf(stderr, "erresc: failed to fetch osc4 color %d\n", num);
	if (xgetcolor(is_osc4 ? num : index, &r, &g, &b)) {
		fprintf(stderr, "erresc: failed to fetch %s color %d\n",
		        is_osc4 ? "osc4" : "osc",
		        is_osc4 ? num : index);
		return;
	}

	n = snprintf(buf, sizeof buf, "\033]4;%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
		     num, r, r, g, g, b, b);

	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]%s%d;rgb:%02x%02x/%02x%02x/%02x%02x\007",
	             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);
	}

	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


@@ 1937,6 1927,11 @@ strhandle(void)
{
	char *p = NULL, *dec;
	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);
	strparse();


@@ 1971,43 1966,22 @@ strhandle(void)
			}
			return;
		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:
			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:
			if (narg < 2)
				break;

			p = strescseq.args[1];

			if (!strcmp(p, "?"))
				osc_color_response(defaultcs, 12);
			else if (xsetcolorname(defaultcs, p))
				fprintf(stderr, "erresc: invalid cursor color: %s\n", p);
			else
			if ((j = par - 10) < 0 || j >= LEN(osc_table))
				break; /* shouldn't be possible */

			if (!strcmp(p, "?")) {
				osc_color_response(par, osc_table[j].idx, 0);
			} else if (xsetcolorname(osc_table[j].idx, p)) {
				fprintf(stderr, "erresc: invalid %s color: %s\n",
				        osc_table[j].str, p);
			} else {
				tfulldirt();
			}
			return;
		case 4: /* color set */
			if (narg < 3)


@@ 2017,9 1991,9 @@ strhandle(void)
		case 104: /* color reset */
			j = (narg > 1) ? atoi(strescseq.args[1]) : -1;

			if (p && !strcmp(p, "?"))
				osc4_color_response(j);
			else if (xsetcolorname(j, p)) {
			if (p && !strcmp(p, "?")) {
				osc_color_response(j, 0, 1);
			} else if (xsetcolorname(j, p)) {
				if (par == 104 && narg <= 1)
					return; /* color reset without parameter */
				fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",

M st.h => st.h +0 -2
@@ 114,8 114,6 @@ void *xmalloc(size_t);
void *xrealloc(void *, size_t);
char *xstrdup(const char *);

int xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b);

/* config.h globals */
extern char *utmp;
extern char *scroll;

M win.h => win.h +1 -0
@@ 30,6 30,7 @@ void xdrawline(Line, int, int, int);
void xfinishdraw(void);
void xloadcols(void);
int xsetcolorname(int, const char *);
int xgetcolor(int, unsigned char *, unsigned char *, unsigned char *);
void xseticontitle(char *);
void xsettitle(char *);
int xsetcursor(int);