code-golfing: cleanup osc color related code - st - Personal fork of st
 (HTM) git clone git://git.drkhsh.at/st.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 8629d9a1da72cc18568a8f146307b0e939b77ebf
 (DIR) parent ef0551932fb162f907b40185d2f48c3b497708ee
 (HTM) Author: NRK <nrk@disroot.org>
       Date:   Fri,  7 Jan 2022 23:21:04 +0600
       
       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.
       
       Diffstat:
         M st.c                                |      90 +++++++++++--------------------
         M st.h                                |       2 --
         M win.h                               |       1 +
       
       3 files changed, 33 insertions(+), 60 deletions(-)
       ---
 (DIR) diff --git a/st.c b/st.c
       @@ -161,6 +161,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);
       @@ -1835,39 +1836,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
       @@ -1875,6 +1865,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();
       @@ -1909,43 +1904,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)
       @@ -1955,9 +1929,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",
 (DIR) diff --git a/st.h b/st.h
       @@ -111,8 +111,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;
 (DIR) diff --git a/win.h b/win.h
       @@ -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);