]> git.armaanb.net Git - st.git/blobdiff - st.c
STREscape: don't trim prematurely
[st.git] / st.c
diff --git a/st.c b/st.c
index b9750f28a4eded5b908675bdbb8bb89aac358a5b..50226d1677b230d290d9e802742e85f27dc1d4b4 100644 (file)
--- a/st.c
+++ b/st.c
  #include <libutil.h>
 #endif
 
-#ifndef __OpenBSD__
-#define pledge(a,b) 0
-#endif
-
 /* Arbitrary sizes */
 #define UTF_INVALID   0xFFFD
 #define UTF_SIZ       4
 
 /* macros */
 #define IS_SET(flag)           ((term.mode & (flag)) != 0)
-#define NUMMAXLEN(x)           ((int)(sizeof(x) * 2.56 + 0.5) + 1)
 #define ISCONTROLC0(c)         (BETWEEN(c, 0, 0x1f) || (c) == '\177')
 #define ISCONTROLC1(c)         (BETWEEN(c, 0x80, 0x9f))
 #define ISCONTROL(c)           (ISCONTROLC0(c) || ISCONTROLC1(c))
-#define ISDELIM(u)             (utf8strchr(worddelimiters, u) != NULL)
-
-/* constants */
-#define ISO14755CMD            "dmenu -w \"$WINDOWID\" -p codepoint: </dev/null"
+#define ISDELIM(u)             (u && wcschr(worddelimiters, u))
 
 enum term_mode {
        MODE_WRAP        = 1 << 0,
@@ -218,7 +210,6 @@ static void selsnap(int *, int *, int);
 static size_t utf8decode(const char *, Rune *, size_t);
 static Rune utf8decodebyte(char, size_t *);
 static char utf8encodebyte(Rune, size_t);
-static char *utf8strchr(char *, Rune);
 static size_t utf8validate(Rune *, size_t);
 
 static char *base64dec(const char *);
@@ -345,23 +336,6 @@ utf8encodebyte(Rune u, size_t i)
        return utfbyte[i] | (u & ~utfmask[i]);
 }
 
-char *
-utf8strchr(char *s, Rune u)
-{
-       Rune r;
-       size_t i, j, len;
-
-       len = strlen(s);
-       for (i = 0, j = 0; i < len; i += j) {
-               if (!(j = utf8decode(&s[i], &r, len - i)))
-                       break;
-               if (r == u)
-                       return &(s[i]);
-       }
-
-       return NULL;
-}
-
 size_t
 utf8validate(Rune *u, size_t i)
 {
@@ -392,7 +366,7 @@ char
 base64dec_getc(const char **src)
 {
        while (**src && !isprint(**src)) (*src)++;
-       return *((*src)++);
+       return **src ? *((*src)++) : '=';  /* emulate padding if string ends */
 }
 
 char *
@@ -410,6 +384,10 @@ base64dec(const char *src)
                int c = base64_digits[(unsigned char) base64dec_getc(&src)];
                int d = base64_digits[(unsigned char) base64dec_getc(&src)];
 
+               /* invalid input. 'a' can be -1, e.g. if src is "\n" (c-str) */
+               if (a == -1 || b == -1)
+                       break;
+
                *dst++ = (a << 2) | ((b & 0x30) >> 4);
                if (c == -1)
                        break;
@@ -484,7 +462,7 @@ selextend(int col, int row, int type, int done)
        selnormalize();
        sel.type = type;
 
-       if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type)
+       if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type || sel.mode == SEL_EMPTY)
                tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey));
 
        sel.mode = done ? SEL_IDLE : SEL_READY;
@@ -739,8 +717,10 @@ sigchld(int a)
        if (pid != p)
                return;
 
-       if (!WIFEXITED(stat) || WEXITSTATUS(stat))
-               die("child finished with error '%d'\n", stat);
+       if (WIFEXITED(stat) && WEXITSTATUS(stat))
+               die("child exited with status %d\n", WEXITSTATUS(stat));
+       else if (WIFSIGNALED(stat))
+               die("child terminated due to signal %d\n", WTERMSIG(stat));
        exit(0);
 }
 
@@ -810,13 +790,17 @@ ttynew(char *line, char *cmd, char *out, char **args)
                        die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
                close(s);
                close(m);
+#ifdef __OpenBSD__
                if (pledge("stdio getpw proc exec", NULL) == -1)
                        die("pledge\n");
+#endif
                execsh(cmd, args);
                break;
        default:
+#ifdef __OpenBSD__
                if (pledge("stdio rpath tty proc", NULL) == -1)
                        die("pledge\n");
+#endif
                close(s);
                cmdfd = m;
                signal(SIGCHLD, sigchld);
@@ -1456,7 +1440,8 @@ tsetattr(int *attr, int l)
                        } else {
                                fprintf(stderr,
                                        "erresc(default): gfx attr %d unknown\n",
-                                       attr[i]), csidump();
+                                       attr[i]);
+                               csidump();
                        }
                        break;
                }
@@ -1576,6 +1561,7 @@ tsetmode(int priv, int set, int *args, int narg)
                        case 1015: /* urxvt mangled mouse mode; incompatible
                                      and can be mistaken for other control
                                      codes. */
+                               break;
                        default:
                                fprintf(stderr,
                                        "erresc: unknown private set/reset mode %d\n",
@@ -1847,7 +1833,7 @@ csireset(void)
 void
 strhandle(void)
 {
-       char *p = NULL;
+       char *p = NULL, *dec;
        int j, narg, par;
 
        term.esc &= ~(ESC_STR_END|ESC_STR);
@@ -1865,8 +1851,6 @@ strhandle(void)
                        return;
                case 52:
                        if (narg > 2) {
-                               char *dec;
-
                                dec = base64dec(strescseq.args[2]);
                                if (dec) {
                                        xsetsel(dec);
@@ -1884,7 +1868,10 @@ strhandle(void)
                case 104: /* color reset, here p = NULL */
                        j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
                        if (xsetcolorname(j, p)) {
-                               fprintf(stderr, "erresc: invalid color %s\n", p);
+                               if (par == 104 && narg <= 1)
+                                       return; /* color reset without parameter */
+                               fprintf(stderr, "erresc: invalid color j=%d, p=%s\n",
+                                       j, p ? p : "(null)");
                        } else {
                                /*
                                 * TODO if defaultbg color is changed, borders
@@ -1981,28 +1968,6 @@ tprinter(char *s, size_t len)
        }
 }
 
-void
-iso14755(const Arg *arg)
-{
-       FILE *p;
-       char *us, *e, codepoint[9], uc[UTF_SIZ];
-       unsigned long utf32;
-
-       if (!(p = popen(ISO14755CMD, "r")))
-               return;
-
-       us = fgets(codepoint, sizeof(codepoint), p);
-       pclose(p);
-
-       if (!us || *us == '\0' || *us == '-' || strlen(us) > 7)
-               return;
-       if ((utf32 = strtoul(us, &e, 16)) == ULONG_MAX ||
-           (*e != '\n' && *e != '\0'))
-               return;
-
-       ttywrite(uc, utf8encode(utf32, uc), 1);
-}
-
 void
 toggleprinter(const Arg *arg)
 {
@@ -2287,7 +2252,7 @@ eschandle(uchar ascii)
        case 'Z': /* DECID -- Identify Terminal */
                ttywrite(vtiden, strlen(vtiden), 0);
                break;
-       case 'c': /* RIS -- Reset to inital state */
+       case 'c': /* RIS -- Reset to initial state */
                treset();
                resettitle();
                xloadcols();
@@ -2358,7 +2323,6 @@ tputc(Rune u)
                        goto check_control_code;
                }
 
-
                if (IS_SET(MODE_SIXEL)) {
                        /* TODO: implement sixel mode */
                        return;
@@ -2366,7 +2330,7 @@ tputc(Rune u)
                if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q')
                        term.mode |= MODE_SIXEL;
 
-               if (strescseq.len+len >= sizeof(strescseq.buf)-1) {
+               if (strescseq.len+len >= sizeof(strescseq.buf)) {
                        /*
                         * Here is a bug in terminals. If the user never sends
                         * some code to stop the str or esc command, then st
@@ -2617,6 +2581,7 @@ draw(void)
                        term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
        term.ocx = cx, term.ocy = term.c.y;
        xfinishdraw();
+       xximspot(term.ocx, term.ocy);
 }
 
 void