[BACK]Return to paste.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/paste.c, Revision 1.17

1.17    ! nicm        1: /* $OpenBSD: paste.c,v 1.16 2014/03/31 21:39:31 nicm Exp $ */
1.1       nicm        2:
                      3: /*
                      4:  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
                     15:  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
                     16:  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
                     19: #include <sys/types.h>
                     20: #include <sys/time.h>
                     21:
1.12      nicm       22: #include <stdlib.h>
1.1       nicm       23: #include <string.h>
1.9       nicm       24: #include <vis.h>
1.1       nicm       25:
                     26: #include "tmux.h"
                     27:
1.7       nicm       28: /*
                     29:  * Stack of paste buffers. Note that paste buffer data is not necessarily a C
                     30:  * string!
                     31:  */
1.1       nicm       32:
1.7       nicm       33: /* Return each item of the stack in turn. */
1.1       nicm       34: struct paste_buffer *
1.11      nicm       35: paste_walk_stack(struct paste_stack *ps, u_int *idx)
1.1       nicm       36: {
                     37:        struct paste_buffer     *pb;
                     38:
                     39:        pb = paste_get_index(ps, *idx);
                     40:        (*idx)++;
                     41:        return (pb);
                     42: }
                     43:
1.7       nicm       44: /* Get the top item on the stack. */
1.1       nicm       45: struct paste_buffer *
                     46: paste_get_top(struct paste_stack *ps)
                     47: {
                     48:        if (ARRAY_LENGTH(ps) == 0)
                     49:                return (NULL);
                     50:        return (ARRAY_FIRST(ps));
                     51: }
                     52:
1.7       nicm       53: /* Get an item by its index. */
1.1       nicm       54: struct paste_buffer *
                     55: paste_get_index(struct paste_stack *ps, u_int idx)
                     56: {
                     57:        if (idx >= ARRAY_LENGTH(ps))
                     58:                return (NULL);
                     59:        return (ARRAY_ITEM(ps, idx));
                     60: }
                     61:
1.7       nicm       62: /* Free the top item on the stack. */
1.1       nicm       63: int
                     64: paste_free_top(struct paste_stack *ps)
                     65: {
                     66:        struct paste_buffer     *pb;
                     67:
                     68:        if (ARRAY_LENGTH(ps) == 0)
                     69:                return (-1);
                     70:
                     71:        pb = ARRAY_FIRST(ps);
                     72:        ARRAY_REMOVE(ps, 0);
                     73:
1.12      nicm       74:        free(pb->data);
                     75:        free(pb);
1.1       nicm       76:
                     77:        return (0);
                     78: }
                     79:
1.7       nicm       80: /* Free an item by index. */
1.1       nicm       81: int
                     82: paste_free_index(struct paste_stack *ps, u_int idx)
                     83: {
                     84:        struct paste_buffer     *pb;
                     85:
                     86:        if (idx >= ARRAY_LENGTH(ps))
                     87:                return (-1);
                     88:
                     89:        pb = ARRAY_ITEM(ps, idx);
                     90:        ARRAY_REMOVE(ps, idx);
                     91:
1.12      nicm       92:        free(pb->data);
                     93:        free(pb);
1.1       nicm       94:
                     95:        return (0);
                     96: }
                     97:
1.8       nicm       98: /*
1.7       nicm       99:  * Add an item onto the top of the stack, freeing the bottom if at limit. Note
                    100:  * that the caller is responsible for allocating data.
                    101:  */
1.1       nicm      102: void
1.7       nicm      103: paste_add(struct paste_stack *ps, char *data, size_t size, u_int limit)
1.1       nicm      104: {
                    105:        struct paste_buffer     *pb;
1.2       nicm      106:
1.7       nicm      107:        if (size == 0)
1.2       nicm      108:                return;
1.1       nicm      109:
1.3       nicm      110:        while (ARRAY_LENGTH(ps) >= limit) {
                    111:                pb = ARRAY_LAST(ps);
1.12      nicm      112:                free(pb->data);
                    113:                free(pb);
1.1       nicm      114:                ARRAY_TRUNC(ps, 1);
1.3       nicm      115:        }
1.1       nicm      116:
                    117:        pb = xmalloc(sizeof *pb);
                    118:        ARRAY_INSERT(ps, 0, pb);
                    119:
                    120:        pb->data = data;
1.4       nicm      121:        pb->size = size;
1.1       nicm      122: }
                    123:
1.7       nicm      124:
1.8       nicm      125: /*
1.7       nicm      126:  * Replace an item on the stack. Note that the caller is responsible for
                    127:  * allocating data.
                    128:  */
1.1       nicm      129: int
1.7       nicm      130: paste_replace(struct paste_stack *ps, u_int idx, char *data, size_t size)
1.1       nicm      131: {
                    132:        struct paste_buffer     *pb;
1.7       nicm      133:
1.15      nicm      134:        if (size == 0) {
                    135:                free(data);
1.7       nicm      136:                return (0);
1.15      nicm      137:        }
1.1       nicm      138:
                    139:        if (idx >= ARRAY_LENGTH(ps))
                    140:                return (-1);
                    141:
                    142:        pb = ARRAY_ITEM(ps, idx);
1.12      nicm      143:        free(pb->data);
1.1       nicm      144:
                    145:        pb->data = data;
1.4       nicm      146:        pb->size = size;
1.1       nicm      147:
                    148:        return (0);
1.9       nicm      149: }
                    150:
1.17    ! nicm      151: /* Convert start of buffer into a nice string. */
1.9       nicm      152: char *
1.17    ! nicm      153: paste_make_sample(struct paste_buffer *pb, int utf8flag)
1.9       nicm      154: {
1.17    ! nicm      155:        char            *buf;
        !           156:        size_t           len, used;
        !           157:        const int        flags = VIS_OCTAL|VIS_TAB|VIS_NL;
        !           158:        const size_t     width = 200;
1.9       nicm      159:
                    160:        len = pb->size;
                    161:        if (len > width)
                    162:                len = width;
1.17    ! nicm      163:        buf = xmalloc(len * 4 + 4);
1.9       nicm      164:
1.17    ! nicm      165:        if (utf8flag)
        !           166:                used = utf8_strvis(buf, pb->data, len, flags);
        !           167:        else
        !           168:                used = strvisx(buf, pb->data, len, flags);
1.13      nicm      169:        if (pb->size > width || used > width)
1.17    ! nicm      170:                strlcpy(buf + width, "...", 4);
1.9       nicm      171:        return (buf);
1.14      nicm      172: }
                    173:
                    174: /* Paste into a window pane, filtering '\n' according to separator. */
                    175: void
1.16      nicm      176: paste_send_pane(struct paste_buffer *pb, struct window_pane *wp,
1.14      nicm      177:     const char *sep, int bracket)
                    178: {
                    179:        const char      *data = pb->data, *end = data + pb->size, *lf;
                    180:        size_t           seplen;
                    181:
                    182:        if (bracket)
                    183:                bufferevent_write(wp->event, "\033[200~", 6);
                    184:
                    185:        seplen = strlen(sep);
                    186:        while ((lf = memchr(data, '\n', end - data)) != NULL) {
                    187:                if (lf != data)
                    188:                        bufferevent_write(wp->event, data, lf - data);
                    189:                bufferevent_write(wp->event, sep, seplen);
                    190:                data = lf + 1;
                    191:        }
                    192:
                    193:        if (end != data)
                    194:                bufferevent_write(wp->event, data, end - data);
                    195:
                    196:        if (bracket)
                    197:                bufferevent_write(wp->event, "\033[201~", 6);
1.1       nicm      198: }