diff --git a/array.h b/array.h index 11e963bc..2c70c310 100644 --- a/array.h +++ b/array.h @@ -39,10 +39,10 @@ fatalx("size too big"); \ if ((a)->space == 0) { \ (a)->space = ARRAY_INITIALSPACE(a); \ - (a)->list = xrealloc((a)->list, 1, (a)->space); \ + (a)->list = xrealloc((a)->list, (a)->space); \ } \ while ((a)->space <= ((a)->num + (n)) * ARRAY_ITEMSIZE(a)) { \ - (a)->list = xrealloc((a)->list, 2, (a)->space); \ + (a)->list = xreallocarray((a)->list, 2, (a)->space); \ (a)->space *= 2; \ } \ } while (0) diff --git a/client.c b/client.c index 6ab53e4f..75f88d2c 100644 --- a/client.c +++ b/client.c @@ -437,15 +437,11 @@ client_signal(int sig, unused short events, unused void *data) struct sigaction sigact; int status; - if (!client_attached) { - switch (sig) { - case SIGCHLD: - waitpid(WAIT_ANY, &status, WNOHANG); - break; - case SIGTERM: + if (sig == SIGCHLD) + waitpid(WAIT_ANY, &status, WNOHANG); + else if (!client_attached) { + if (sig == SIGTERM) event_loopexit(NULL); - break; - } } else { switch (sig) { case SIGHUP: diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c index 0efe1cd0..bddb7627 100644 --- a/cmd-capture-pane.c +++ b/cmd-capture-pane.c @@ -48,7 +48,7 @@ const struct cmd_entry cmd_capture_pane_entry = { char * cmd_capture_pane_append(char *buf, size_t *len, char *line, size_t linelen) { - buf = xrealloc(buf, 1, *len + linelen + 1); + buf = xrealloc(buf, *len + linelen + 1); memcpy(buf + *len, line, linelen); *len += linelen; return (buf); diff --git a/cmd-save-buffer.c b/cmd-save-buffer.c index 8dd52c96..164d7d56 100644 --- a/cmd-save-buffer.c +++ b/cmd-save-buffer.c @@ -146,7 +146,7 @@ do_print: size = pb->size - used; msglen = size * 4 + 1; - msg = xrealloc(msg, 1, msglen); + msg = xrealloc(msg, msglen); strvisx(msg, start, size, VIS_OCTAL|VIS_TAB); cmdq_print(cmdq, "%s", msg); diff --git a/cmd-set-buffer.c b/cmd-set-buffer.c index 82922279..a5ecfef4 100644 --- a/cmd-set-buffer.c +++ b/cmd-set-buffer.c @@ -104,7 +104,7 @@ cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq) memcpy(pdata, pb->data, psize); } - pdata = xrealloc(pdata, 1, psize + newsize); + pdata = xrealloc(pdata, psize + newsize); memcpy(pdata + psize, args->argv[0], newsize); psize += newsize; diff --git a/cmd-string.c b/cmd-string.c index e793ea02..fd483070 100644 --- a/cmd-string.c +++ b/cmd-string.c @@ -107,10 +107,11 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file, case ' ': case '\t': if (buf != NULL) { - buf = xrealloc(buf, 1, len + 1); + buf = xrealloc(buf, len + 1); buf[len] = '\0'; - argv = xrealloc(argv, argc + 1, sizeof *argv); + argv = xreallocarray(argv, argc + 1, + sizeof *argv); argv[argc++] = buf; buf = NULL; @@ -151,7 +152,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file, if (len >= SIZE_MAX - 2) goto error; - buf = xrealloc(buf, 1, len + 1); + buf = xrealloc(buf, len + 1); buf[len++] = ch; break; } @@ -179,7 +180,7 @@ cmd_string_copy(char **dst, char *src, size_t *len) srclen = strlen(src); - *dst = xrealloc(*dst, 1, *len + srclen + 1); + *dst = xrealloc(*dst, *len + srclen + 1); strlcpy(*dst + *len, src, srclen + 1); *len += srclen; @@ -231,11 +232,11 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc) if (len >= SIZE_MAX - 2) goto error; - buf = xrealloc(buf, 1, len + 1); + buf = xrealloc(buf, len + 1); buf[len++] = ch; } - buf = xrealloc(buf, 1, len + 1); + buf = xrealloc(buf, len + 1); buf[len] = '\0'; return (buf); @@ -278,7 +279,7 @@ cmd_string_variable(const char *s, size_t *p) return (t); } - buf = xrealloc(buf, 1, len + 1); + buf = xrealloc(buf, len + 1); buf[len++] = ch; for (;;) { @@ -288,7 +289,7 @@ cmd_string_variable(const char *s, size_t *p) else { if (len >= SIZE_MAX - 3) goto error; - buf = xrealloc(buf, 1, len + 1); + buf = xrealloc(buf, len + 1); buf[len++] = ch; } } @@ -299,7 +300,7 @@ cmd_string_variable(const char *s, size_t *p) if (ch != EOF && fch != '{') cmd_string_ungetc(p); /* ch */ - buf = xrealloc(buf, 1, len + 1); + buf = xrealloc(buf, len + 1); buf[len] = '\0'; envent = environ_find(&global_environ, buf); diff --git a/cmd.c b/cmd.c index f5165a5f..a8275f88 100644 --- a/cmd.c +++ b/cmd.c @@ -120,7 +120,7 @@ struct session *cmd_choose_session_list(struct sessionslist *); struct session *cmd_choose_session(int); struct client *cmd_choose_client(struct clients *); struct client *cmd_lookup_client(const char *); -struct session *cmd_lookup_session(const char *, int *); +struct session *cmd_lookup_session(struct cmd_q *, const char *, int *); struct session *cmd_lookup_session_id(const char *); struct winlink *cmd_lookup_window(struct session *, const char *, int *); int cmd_lookup_index(struct session *, const char *, int *); @@ -221,7 +221,7 @@ cmd_stringify_argv(int argc, char **argv) for (i = 0; i < argc; i++) { len += strlen(argv[i]) + 1; - buf = xrealloc(buf, 1, len); + buf = xrealloc(buf, len); if (i == 0) *buf = '\0'; @@ -584,9 +584,11 @@ cmd_lookup_session_id(const char *arg) /* Lookup a session by name. If no session is found, NULL is returned. */ struct session * -cmd_lookup_session(const char *name, int *ambiguous) +cmd_lookup_session(struct cmd_q *cmdq, const char *name, int *ambiguous) { - struct session *s, *sfound; + struct session *s, *sfound; + struct window *w; + struct window_pane *wp; *ambiguous = 0; @@ -594,6 +596,12 @@ cmd_lookup_session(const char *name, int *ambiguous) if ((s = cmd_lookup_session_id(name)) != NULL) return (s); + /* Try as pane or window id. */ + if ((wp = cmd_lookup_paneid(name)) != NULL) + return (cmd_window_session(cmdq, wp->window, NULL)); + if ((w = cmd_lookup_windowid(name)) != NULL) + return (cmd_window_session(cmdq, w, NULL)); + /* * Look for matches. First look for exact matches - session names must * be unique so an exact match can't be ambigious and can just be @@ -629,16 +637,30 @@ cmd_lookup_session(const char *name, int *ambiguous) struct winlink * cmd_lookup_window(struct session *s, const char *name, int *ambiguous) { - struct winlink *wl, *wlfound; - const char *errstr; - u_int idx; + struct winlink *wl, *wlfound; + struct window *w; + struct window_pane *wp; + const char *errstr; + u_int idx; *ambiguous = 0; - /* Try as a window id. */ + /* Try as pane or window id. */ if ((wl = cmd_lookup_winlink_windowid(s, name)) != NULL) return (wl); + /* Lookup as pane or window id. */ + if ((wp = cmd_lookup_paneid(name)) != NULL) { + wl = winlink_find_by_window(&s->windows, wp->window); + if (wl != NULL) + return (wl); + } + if ((w = cmd_lookup_windowid(name)) != NULL) { + wl = winlink_find_by_window(&s->windows, w); + if (wl != NULL) + return (wl); + } + /* First see if this is a valid window index in this session. */ idx = strtonum(name, 0, INT_MAX, &errstr); if (errstr == NULL) { @@ -785,13 +807,11 @@ cmd_window_session(struct cmd_q *cmdq, struct window *w, struct winlink **wlp) struct session * cmd_find_session(struct cmd_q *cmdq, const char *arg, int prefer_unattached) { - struct session *s; - struct window_pane *wp; - struct window *w; - struct client *c; - char *tmparg; - size_t arglen; - int ambiguous; + struct session *s; + struct client *c; + char *tmparg; + size_t arglen; + int ambiguous; /* A NULL argument means the current session. */ if (arg == NULL) { @@ -800,12 +820,6 @@ cmd_find_session(struct cmd_q *cmdq, const char *arg, int prefer_unattached) return (s); } - /* Lookup as pane id or window id. */ - if ((wp = cmd_lookup_paneid(arg)) != NULL) - return (cmd_window_session(cmdq, wp->window, NULL)); - if ((w = cmd_lookup_windowid(arg)) != NULL) - return (cmd_window_session(cmdq, w, NULL)); - /* Trim a single trailing colon if any. */ tmparg = xstrdup(arg); arglen = strlen(tmparg); @@ -821,7 +835,7 @@ cmd_find_session(struct cmd_q *cmdq, const char *arg, int prefer_unattached) } /* Find the session, if any. */ - s = cmd_lookup_session(tmparg, &ambiguous); + s = cmd_lookup_session(cmdq, tmparg, &ambiguous); /* If it doesn't, try to match it as a client. */ if (s == NULL && (c = cmd_lookup_client(tmparg)) != NULL) @@ -843,12 +857,11 @@ cmd_find_session(struct cmd_q *cmdq, const char *arg, int prefer_unattached) struct winlink * cmd_find_window(struct cmd_q *cmdq, const char *arg, struct session **sp) { - struct session *s; - struct winlink *wl; - struct window_pane *wp; - const char *winptr; - char *sessptr = NULL; - int ambiguous = 0; + struct session *s; + struct winlink *wl; + const char *winptr; + char *sessptr = NULL; + int ambiguous = 0; /* * Find the current session. There must always be a current session, if @@ -866,14 +879,6 @@ cmd_find_window(struct cmd_q *cmdq, const char *arg, struct session **sp) return (s->curw); } - /* Lookup as pane id. */ - if ((wp = cmd_lookup_paneid(arg)) != NULL) { - s = cmd_window_session(cmdq, wp->window, &wl); - if (sp != NULL) - *sp = s; - return (wl); - } - /* Time to look at the argument. If it is empty, that is an error. */ if (*arg == '\0') goto not_found; @@ -888,7 +893,7 @@ cmd_find_window(struct cmd_q *cmdq, const char *arg, struct session **sp) /* Try to lookup the session if present. */ if (*sessptr != '\0') { - if ((s = cmd_lookup_session(sessptr, &ambiguous)) == NULL) + if ((s = cmd_lookup_session(cmdq, sessptr, &ambiguous)) == NULL) goto no_session; } if (sp != NULL) @@ -939,7 +944,8 @@ no_colon: lookup_session: if (ambiguous) goto not_found; - if (*arg != '\0' && (s = cmd_lookup_session(arg, &ambiguous)) == NULL) + if (*arg != '\0' && + (s = cmd_lookup_session(cmdq, arg, &ambiguous)) == NULL) goto no_session; if (sp != NULL) @@ -1029,7 +1035,7 @@ cmd_find_index(struct cmd_q *cmdq, const char *arg, struct session **sp) /* Try to lookup the session if present. */ if (sessptr != NULL && *sessptr != '\0') { - if ((s = cmd_lookup_session(sessptr, &ambiguous)) == NULL) + if ((s = cmd_lookup_session(cmdq, sessptr, &ambiguous)) == NULL) goto no_session; } if (sp != NULL) @@ -1077,7 +1083,8 @@ no_colon: lookup_session: if (ambiguous) goto not_found; - if (*arg != '\0' && (s = cmd_lookup_session(arg, &ambiguous)) == NULL) + if (*arg != '\0' && + (s = cmd_lookup_session(cmdq, arg, &ambiguous)) == NULL) goto no_session; if (sp != NULL) @@ -1191,7 +1198,13 @@ cmd_find_pane(struct cmd_q *cmdq, *wpp = wl->window->active; else if (paneptr[0] == '+' || paneptr[0] == '-') *wpp = cmd_find_pane_offset(paneptr, wl); - else { + else if (paneptr[0] == '!' && paneptr[1] == '\0') { + if (wl->window->last == NULL) { + cmdq_error(cmdq, "no last pane"); + goto error; + } + *wpp = wl->window->last; + } else { idx = strtonum(paneptr, 0, INT_MAX, &errstr); if (errstr != NULL) goto lookup_string; @@ -1288,11 +1301,11 @@ cmd_template_replace(const char *template, const char *s, int idx) ptr++; len += strlen(s); - buf = xrealloc(buf, 1, len + 1); + buf = xrealloc(buf, len + 1); strlcat(buf, s, len + 1); continue; } - buf = xrealloc(buf, 1, len + 2); + buf = xrealloc(buf, len + 2); buf[len++] = ch; buf[len] = '\0'; } diff --git a/format.c b/format.c index baf23ec1..619f89fe 100644 --- a/format.c +++ b/format.c @@ -267,7 +267,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, /* Expand the buffer and copy in the value. */ while (*len - *off < valuelen + 1) { - *buf = xrealloc(*buf, 2, *len); + *buf = xreallocarray(*buf, 2, *len); *len *= 2; } memcpy(*buf + *off, value, valuelen); @@ -298,7 +298,7 @@ format_expand(struct format_tree *ft, const char *fmt) while (*fmt != '\0') { if (*fmt != '#') { while (len - off < 2) { - buf = xrealloc(buf, 2, len); + buf = xreallocarray(buf, 2, len); len *= 2; } buf[off++] = *fmt++; @@ -326,7 +326,7 @@ format_expand(struct format_tree *ft, const char *fmt) continue; case '#': while (len - off < 2) { - buf = xrealloc(buf, 2, len); + buf = xreallocarray(buf, 2, len); len *= 2; } buf[off++] = '#'; @@ -339,7 +339,7 @@ format_expand(struct format_tree *ft, const char *fmt) s = format_lower[ch - 'a']; if (s == NULL) { while (len - off < 3) { - buf = xrealloc(buf, 2, len); + buf = xreallocarray(buf, 2, len); len *= 2; } buf[off++] = '#'; diff --git a/grid.c b/grid.c index 6b8cfcb7..521fb9fd 100644 --- a/grid.c +++ b/grid.c @@ -172,7 +172,8 @@ grid_scroll_history(struct grid *gd) u_int yy; yy = gd->hsize + gd->sy; - gd->linedata = xrealloc(gd->linedata, yy + 1, sizeof *gd->linedata); + gd->linedata = xreallocarray(gd->linedata, yy + 1, + sizeof *gd->linedata); memset(&gd->linedata[yy], 0, sizeof gd->linedata[yy]); gd->hsize++; @@ -187,7 +188,8 @@ grid_scroll_history_region(struct grid *gd, u_int upper, u_int lower) /* Create a space for a new line. */ yy = gd->hsize + gd->sy; - gd->linedata = xrealloc(gd->linedata, yy + 1, sizeof *gd->linedata); + gd->linedata = xreallocarray(gd->linedata, yy + 1, + sizeof *gd->linedata); /* Move the entire screen down to free a space for this line. */ gl_history = &gd->linedata[gd->hsize]; @@ -221,7 +223,7 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx) if (sx <= gl->cellsize) return; - gl->celldata = xrealloc(gl->celldata, sx, sizeof *gl->celldata); + gl->celldata = xreallocarray(gl->celldata, sx, sizeof *gl->celldata); for (xx = gl->cellsize; xx < sx; xx++) grid_put_cell(gd, xx, py, &grid_default_cell); gl->cellsize = sx; @@ -610,7 +612,7 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx, } while (len < off + size + codelen + 1) { - buf = xrealloc(buf, 2, len); + buf = xreallocarray(buf, 2, len); len *= 2; } @@ -685,7 +687,7 @@ grid_reflow_join(struct grid *dst, u_int *py, struct grid_line *src_gl, nx = ox + to_copy; /* Resize the destination line. */ - dst_gl->celldata = xrealloc(dst_gl->celldata, nx, + dst_gl->celldata = xreallocarray(dst_gl->celldata, nx, sizeof *dst_gl->celldata); dst_gl->cellsize = nx; @@ -724,7 +726,8 @@ grid_reflow_split(struct grid *dst, u_int *py, struct grid_line *src_gl, to_copy = src_gl->cellsize; /* Expand destination line. */ - dst_gl->celldata = xmalloc(to_copy * sizeof *dst_gl->celldata); + dst_gl->celldata = xreallocarray(NULL, to_copy, + sizeof *dst_gl->celldata); dst_gl->cellsize = to_copy; dst_gl->flags |= GRID_LINE_WRAPPED; diff --git a/input.c b/input.c index 06e940aa..12459675 100644 --- a/input.c +++ b/input.c @@ -909,7 +909,7 @@ input_ground(struct input_ctx *ictx) if (ictx->input_space > INPUT_BUF_START) { ictx->input_space = INPUT_BUF_START; - ictx->input_buf = xrealloc(ictx->input_buf, 1, INPUT_BUF_START); + ictx->input_buf = xrealloc(ictx->input_buf, INPUT_BUF_START); } } @@ -974,7 +974,7 @@ input_input(struct input_ctx *ictx) ictx->flags |= INPUT_DISCARD; return (0); } - ictx->input_buf = xrealloc(ictx->input_buf, 1, available); + ictx->input_buf = xrealloc(ictx->input_buf, available); ictx->input_space = available; } ictx->input_buf[ictx->input_len++] = ictx->ch; diff --git a/paste.c b/paste.c index 4af8cccf..ce1f27d3 100644 --- a/paste.c +++ b/paste.c @@ -278,7 +278,7 @@ paste_make_sample(struct paste_buffer *pb, int utf8flag) len = pb->size; if (len > width) len = width; - buf = xmalloc(len * 4 + 4); + buf = xreallocarray(NULL, len, 4 + 4); if (utf8flag) used = utf8_strvis(buf, pb->data, len, flags); diff --git a/screen-write.c b/screen-write.c index 325fb9a4..8c059d15 100644 --- a/screen-write.c +++ b/screen-write.c @@ -990,6 +990,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc); grid_cell_get(gc, &ud); grid_cell_set(&tmp_gc, &ud); + tmp_gc.attr = tmp_gc.attr & ~GRID_ATTR_CHARSET; + tmp_gc.attr |= gc->attr & GRID_ATTR_CHARSET; tmp_gc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256); tmp_gc.flags |= s->sel.cell.flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); diff --git a/screen.c b/screen.c index 014e4f31..e400111f 100644 --- a/screen.c +++ b/screen.c @@ -216,8 +216,8 @@ screen_resize_y(struct screen *s, u_int sy) } /* Resize line arrays. */ - gd->linedata = xrealloc( - gd->linedata, gd->hsize + sy, sizeof *gd->linedata); + gd->linedata = xreallocarray(gd->linedata, gd->hsize + sy, + sizeof *gd->linedata); /* Size increasing. */ if (sy > oldy) { diff --git a/server-client.c b/server-client.c index 08085f75..45cc40ca 100644 --- a/server-client.c +++ b/server-client.c @@ -328,6 +328,7 @@ server_client_check_mouse(struct client *c, struct window_pane *wp) if (options_get_number(oo, "mouse-select-pane") && (m->event == MOUSE_EVENT_DOWN || m->event == MOUSE_EVENT_WHEEL)) { window_set_active_at(wp->window, m->x, m->y); + server_status_window(wp->window); server_redraw_window_borders(wp->window); wp = wp->window->active; /* may have changed */ } diff --git a/status.c b/status.c index deb1b60d..a480b09d 100644 --- a/status.c +++ b/status.c @@ -121,12 +121,17 @@ status_set_window_at(struct client *c, u_int x) { struct session *s = c->session; struct winlink *wl; + struct options *oo; + size_t len; x += c->wlmouse; RB_FOREACH(wl, winlinks, &s->windows) { + oo = &wl->window->options; + + len = strlen(options_get_string(oo, "window-status-separator")); if (x < wl->status_width && session_select(s, wl->idx) == 0) server_redraw_session(s); - x -= wl->status_width + 1; + x -= wl->status_width + len; } } @@ -987,7 +992,7 @@ status_prompt_key(struct client *c, int key) /* Insert the new word. */ size += strlen(s); off = first - c->prompt_buffer; - c->prompt_buffer = xrealloc(c->prompt_buffer, 1, size + 1); + c->prompt_buffer = xrealloc(c->prompt_buffer, size + 1); first = c->prompt_buffer + off; memmove(first + strlen(s), first, n); memcpy(first, s, strlen(s)); @@ -1165,7 +1170,7 @@ status_prompt_key(struct client *c, int key) break; } - c->prompt_buffer = xrealloc(c->prompt_buffer, 1, size + n + 1); + c->prompt_buffer = xrealloc(c->prompt_buffer, size + n + 1); if (c->prompt_index == size) { memcpy(c->prompt_buffer + c->prompt_index, pb->data, n); c->prompt_index += n; @@ -1205,7 +1210,7 @@ status_prompt_key(struct client *c, int key) case MODEKEY_OTHER: if ((key & 0xff00) != 0 || key < 32 || key == 127) break; - c->prompt_buffer = xrealloc(c->prompt_buffer, 1, size + 2); + c->prompt_buffer = xrealloc(c->prompt_buffer, size + 2); if (c->prompt_index == size) { c->prompt_buffer[c->prompt_index++] = key; diff --git a/tmux.1 b/tmux.1 index 8afc3c5e..cd738c34 100644 --- a/tmux.1 +++ b/tmux.1 @@ -439,10 +439,11 @@ first attempts to use the argument as a pane index; if that fails, it is looked up as for .Ar target-window . A -.Ql + -or +.Ql + , .Ql - -indicate the next or previous pane index, respectively. +or +.Ql \&! +indicate the next, previous or last pane. One of the strings .Em top , .Em bottom , @@ -1859,7 +1860,7 @@ In addition, the following special key names are accepted: .Em Escape , .Em F1 to -.Em F20 , +.Em F12 , .Em Home , .Em IC (Insert), diff --git a/tmux.h b/tmux.h index 5ffc07cd..7e8dcb0f 100644 --- a/tmux.h +++ b/tmux.h @@ -2407,7 +2407,8 @@ __dead void printflike1 log_fatalx(const char *, ...); char *xstrdup(const char *); void *xcalloc(size_t, size_t); void *xmalloc(size_t); -void *xrealloc(void *, size_t, size_t); +void *xrealloc(void *, size_t); +void *xreallocarray(void *, size_t, size_t); int printflike2 xasprintf(char **, const char *, ...); int xvasprintf(char **, const char *, va_list); int printflike3 xsnprintf(char *, size_t, const char *, ...); diff --git a/tty-acs.c b/tty-acs.c index ae84f0d4..140ad4d6 100644 --- a/tty-acs.c +++ b/tty-acs.c @@ -81,7 +81,7 @@ tty_acs_get(struct tty *tty, u_char ch) struct tty_acs_entry *entry; /* If not a UTF-8 terminal, use the ACS set. */ - if (!(tty->flags & TTY_UTF8)) { + if (tty != NULL && !(tty->flags & TTY_UTF8)) { if (tty->term->acs[ch][0] == '\0') return (NULL); return (&tty->term->acs[ch][0]); diff --git a/utf8.c b/utf8.c index 4b2560c4..58475405 100644 --- a/utf8.c +++ b/utf8.c @@ -420,7 +420,7 @@ utf8_fromcstr(const char *src) n = 0; while (*src != '\0') { - dst = xrealloc(dst, n + 1, sizeof *dst); + dst = xreallocarray(dst, n + 1, sizeof *dst); if (utf8_open(&dst[n], *src)) { more = 1; while (*++src != '\0' && more) @@ -437,7 +437,7 @@ utf8_fromcstr(const char *src) n++; } - dst = xrealloc(dst, n + 1, sizeof *dst); + dst = xreallocarray(dst, n + 1, sizeof *dst); dst[n].size = 0; return (dst); } @@ -453,12 +453,12 @@ utf8_tocstr(struct utf8_data *src) n = 0; for(; src->size != 0; src++) { - dst = xrealloc(dst, n + src->size, 1); + dst = xreallocarray(dst, n + src->size, 1); memcpy(dst + n, src->data, src->size); n += src->size; } - dst = xrealloc(dst, n + 1, 1); + dst = xreallocarray(dst, n + 1, 1); dst[n] = '\0'; return (dst); } diff --git a/window-choose.c b/window-choose.c index 23e77b32..2bceaa41 100644 --- a/window-choose.c +++ b/window-choose.c @@ -317,7 +317,7 @@ window_choose_prompt_input(enum window_choose_input_type input_type, data->input_prompt = prompt; input_len = strlen(data->input_str) + 2; - data->input_str = xrealloc(data->input_str, 1, input_len); + data->input_str = xrealloc(data->input_str, input_len); data->input_str[input_len - 2] = key; data->input_str[input_len - 1] = '\0'; diff --git a/window-copy.c b/window-copy.c index 3ac994d3..542c28ac 100644 --- a/window-copy.c +++ b/window-copy.c @@ -794,7 +794,7 @@ window_copy_key_input(struct window_pane *wp, int key) } inputlen = strlen(data->inputstr); - data->inputstr = xrealloc(data->inputstr, 1, inputlen + n + 1); + data->inputstr = xrealloc(data->inputstr, inputlen + n + 1); memcpy(data->inputstr + inputlen, pb->data, n); data->inputstr[inputlen + n] = '\0'; break; @@ -840,7 +840,7 @@ window_copy_key_input(struct window_pane *wp, int key) break; inputlen = strlen(data->inputstr) + 2; - data->inputstr = xrealloc(data->inputstr, 1, inputlen); + data->inputstr = xrealloc(data->inputstr, inputlen); data->inputstr[inputlen - 2] = key; data->inputstr[inputlen - 1] = '\0'; break; @@ -1533,7 +1533,7 @@ window_copy_append_selection(struct window_pane *wp, const char *bufname) } else pb = paste_get_name(bufname); if (pb != NULL) { - buf = xrealloc(buf, 1, len + pb->size); + buf = xrealloc(buf, len + pb->size); memmove(buf + pb->size, buf, len); memcpy(buf, pb->data, pb->size); len += pb->size; @@ -1552,6 +1552,7 @@ window_copy_copy_line(struct window_pane *wp, struct grid_line *gl; struct utf8_data ud; u_int i, xx, wrapped = 0; + const char *s; if (sx > ex) return; @@ -1580,8 +1581,15 @@ window_copy_copy_line(struct window_pane *wp, if (gc->flags & GRID_FLAG_PADDING) continue; grid_cell_get(gc, &ud); + if (ud.size == 1 && (gc->attr & GRID_ATTR_CHARSET)) { + s = tty_acs_get(NULL, ud.data[0]); + if (s != NULL && strlen(s) <= sizeof ud.data) { + ud.size = strlen(s); + memcpy (ud.data, s, ud.size); + } + } - *buf = xrealloc(*buf, 1, (*off) + ud.size); + *buf = xrealloc(*buf, (*off) + ud.size); memcpy(*buf + *off, ud.data, ud.size); *off += ud.size; } @@ -1589,7 +1597,7 @@ window_copy_copy_line(struct window_pane *wp, /* Only add a newline if the line wasn't wrapped. */ if (!wrapped || ex != xx) { - *buf = xrealloc(*buf, 1, (*off) + 1); + *buf = xrealloc(*buf, (*off) + 1); (*buf)[(*off)++] = '\n'; } } diff --git a/xmalloc.c b/xmalloc.c index df583e55..a1bc6b8f 100644 --- a/xmalloc.c +++ b/xmalloc.c @@ -67,7 +67,20 @@ xmalloc(size_t size) } void * -xrealloc(void *oldptr, size_t nmemb, size_t size) +xrealloc(void *oldptr, size_t newsize) +{ + void *newptr; + + if (newsize == 0) + fatalx("zero size"); + if ((newptr = realloc(oldptr, newsize)) == NULL) + fatal("xrealloc failed"); + + return (newptr); +} + +void * +xreallocarray(void *oldptr, size_t nmemb, size_t size) { size_t newsize = nmemb * size; void *newptr; @@ -77,7 +90,7 @@ xrealloc(void *oldptr, size_t nmemb, size_t size) if (SIZE_MAX / nmemb < size) fatalx("nmemb * size > SIZE_MAX"); if ((newptr = realloc(oldptr, newsize)) == NULL) - fatal("xrealloc failed"); + fatal("xreallocarray failed"); return (newptr); }