#include <errno.h>
#include <fcntl.h>
#include <limits.h>
-#include <locale.h>
#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
-#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/select.h>
-#include <sys/stat.h>
-#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <termios.h>
-#include <time.h>
#include <unistd.h>
-#include <libgen.h>
#include <wchar.h>
+#include <wctype.h>
#include "st.h"
#include "win.h"
/* 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) ((iswspace(u) || iswpunct(u)) && wcschr(extrawordchars, u) == NULL)
enum term_mode {
MODE_WRAP = 1 << 0,
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 *);
void *
xmalloc(size_t len)
{
- void *p = malloc(len);
+ void *p;
- if (!p)
- die("Out of memory\n");
+ if (!(p = malloc(len)))
+ die("malloc: %s\n", strerror(errno));
return p;
}
xrealloc(void *p, size_t len)
{
if ((p = realloc(p, len)) == NULL)
- die("Out of memory\n");
+ die("realloc: %s\n", strerror(errno));
return p;
}
xstrdup(char *s)
{
if ((s = strdup(s)) == NULL)
- die("Out of memory\n");
+ die("strdup: %s\n", strerror(errno));
return s;
}
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)
{
selclear();
sel.mode = SEL_EMPTY;
sel.type = SEL_REGULAR;
+ sel.alt = IS_SET(MODE_ALTSCREEN);
sel.snap = snap;
sel.oe.x = sel.ob.x = col;
sel.oe.y = sel.ob.y = row;
{
int oldey, oldex, oldsby, oldsey, oldtype;
- if (!sel.mode)
+ if (sel.mode == SEL_IDLE)
return;
if (done && sel.mode == SEL_EMPTY) {
selclear();
oldsey = sel.ne.y;
oldtype = sel.type;
- sel.alt = IS_SET(MODE_ALTSCREEN);
sel.oe.x = col;
sel.oe.y = row;
selnormalize();
errno = 0;
if ((pw = getpwuid(getuid())) == NULL) {
if (errno)
- die("getpwuid:%s\n", strerror(errno));
+ die("getpwuid: %s\n", strerror(errno));
else
die("who are you?\n");
}
pid_t p;
if ((p = waitpid(pid, &stat, WNOHANG)) < 0)
- die("Waiting for pid %hd failed: %s\n", pid, strerror(errno));
+ die("waiting for pid %hd failed: %s\n", pid, strerror(errno));
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);
}
-
void
stty(char **args)
{
}
*q = '\0';
if (system(cmd) != 0)
- perror("Couldn't call stty");
+ perror("Couldn't call stty");
}
int
if (line) {
if ((cmdfd = open(line, O_RDWR)) < 0)
- die("open line failed: %s\n", strerror(errno));
+ die("open line '%s' failed: %s\n",
+ line, strerror(errno));
dup2(cmdfd, 0);
stty(args);
return cmdfd;
switch (pid = fork()) {
case -1:
- die("fork failed\n");
+ die("fork failed: %s\n", strerror(errno));
break;
case 0:
close(iofd);
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);
/* append read bytes to unprocessed bytes */
if ((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0)
- die("Couldn't read from shell: %s\n", strerror(errno));
+ die("couldn't read from shell: %s\n", strerror(errno));
buflen += ret;
written = twrite(buf, buflen, 0);
} else {
fprintf(stderr,
"erresc(default): gfx attr %d unknown\n",
- attr[i]), csidump();
+ attr[i]);
+ csidump();
}
break;
}
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",
tputtab(csiescseq.arg[0]);
break;
case 'J': /* ED -- Clear screen */
- selclear();
switch (csiescseq.arg[0]) {
case 0: /* below */
tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
void
strhandle(void)
{
- char *p = NULL;
+ char *p = NULL, *dec;
int j, narg, par;
term.esc &= ~(ESC_STR_END|ESC_STR);
return;
case 52:
if (narg > 2) {
- char *dec;
-
dec = base64dec(strescseq.args[2]);
if (dec) {
xsetsel(dec);
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
}
}
-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)
{
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();
goto check_control_code;
}
-
if (IS_SET(MODE_SIXEL)) {
/* TODO: implement sixel mode */
return;
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