[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.18

1.18    ! nicm        1: /* $OpenBSD: paste.c,v 1.17 2014/04/02 18:12:18 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.18    ! nicm       33: ARRAY_DECL(, struct paste_buffer *) paste_buffers =  ARRAY_INITIALIZER;
        !            34:
1.7       nicm       35: /* Return each item of the stack in turn. */
1.1       nicm       36: struct paste_buffer *
1.18    ! nicm       37: paste_walk_stack(u_int *idx)
1.1       nicm       38: {
                     39:        struct paste_buffer     *pb;
                     40:
1.18    ! nicm       41:        pb = paste_get_index(*idx);
1.1       nicm       42:        (*idx)++;
                     43:        return (pb);
                     44: }
                     45:
1.7       nicm       46: /* Get the top item on the stack. */
1.1       nicm       47: struct paste_buffer *
1.18    ! nicm       48: paste_get_top(void)
1.1       nicm       49: {
1.18    ! nicm       50:        if (ARRAY_LENGTH(&paste_buffers) == 0)
1.1       nicm       51:                return (NULL);
1.18    ! nicm       52:        return (ARRAY_FIRST(&paste_buffers));
1.1       nicm       53: }
                     54:
1.7       nicm       55: /* Get an item by its index. */
1.1       nicm       56: struct paste_buffer *
1.18    ! nicm       57: paste_get_index(u_int idx)
1.1       nicm       58: {
1.18    ! nicm       59:        if (idx >= ARRAY_LENGTH(&paste_buffers))
1.1       nicm       60:                return (NULL);
1.18    ! nicm       61:        return (ARRAY_ITEM(&paste_buffers, idx));
1.1       nicm       62: }
                     63:
1.7       nicm       64: /* Free the top item on the stack. */
1.1       nicm       65: int
1.18    ! nicm       66: paste_free_top(void)
1.1       nicm       67: {
                     68:        struct paste_buffer     *pb;
                     69:
1.18    ! nicm       70:        if (ARRAY_LENGTH(&paste_buffers) == 0)
1.1       nicm       71:                return (-1);
                     72:
1.18    ! nicm       73:        pb = ARRAY_FIRST(&paste_buffers);
        !            74:        ARRAY_REMOVE(&paste_buffers, 0);
1.1       nicm       75:
1.12      nicm       76:        free(pb->data);
                     77:        free(pb);
1.1       nicm       78:
                     79:        return (0);
                     80: }
                     81:
1.7       nicm       82: /* Free an item by index. */
1.1       nicm       83: int
1.18    ! nicm       84: paste_free_index(u_int idx)
1.1       nicm       85: {
                     86:        struct paste_buffer     *pb;
                     87:
1.18    ! nicm       88:        if (idx >= ARRAY_LENGTH(&paste_buffers))
1.1       nicm       89:                return (-1);
                     90:
1.18    ! nicm       91:        pb = ARRAY_ITEM(&paste_buffers, idx);
        !            92:        ARRAY_REMOVE(&paste_buffers, idx);
1.1       nicm       93:
1.12      nicm       94:        free(pb->data);
                     95:        free(pb);
1.1       nicm       96:
                     97:        return (0);
                     98: }
                     99:
1.8       nicm      100: /*
1.7       nicm      101:  * Add an item onto the top of the stack, freeing the bottom if at limit. Note
                    102:  * that the caller is responsible for allocating data.
                    103:  */
1.1       nicm      104: void
1.18    ! nicm      105: paste_add(char *data, size_t size, u_int limit)
1.1       nicm      106: {
                    107:        struct paste_buffer     *pb;
1.2       nicm      108:
1.7       nicm      109:        if (size == 0)
1.2       nicm      110:                return;
1.1       nicm      111:
1.18    ! nicm      112:        while (ARRAY_LENGTH(&paste_buffers) >= limit) {
        !           113:                pb = ARRAY_LAST(&paste_buffers);
1.12      nicm      114:                free(pb->data);
                    115:                free(pb);
1.18    ! nicm      116:                ARRAY_TRUNC(&paste_buffers, 1);
1.3       nicm      117:        }
1.1       nicm      118:
                    119:        pb = xmalloc(sizeof *pb);
1.18    ! nicm      120:        ARRAY_INSERT(&paste_buffers, 0, pb);
1.1       nicm      121:
                    122:        pb->data = data;
1.4       nicm      123:        pb->size = size;
1.1       nicm      124: }
                    125:
1.7       nicm      126:
1.8       nicm      127: /*
1.7       nicm      128:  * Replace an item on the stack. Note that the caller is responsible for
                    129:  * allocating data.
                    130:  */
1.1       nicm      131: int
1.18    ! nicm      132: paste_replace(u_int idx, char *data, size_t size)
1.1       nicm      133: {
                    134:        struct paste_buffer     *pb;
1.7       nicm      135:
1.15      nicm      136:        if (size == 0) {
                    137:                free(data);
1.7       nicm      138:                return (0);
1.15      nicm      139:        }
1.1       nicm      140:
1.18    ! nicm      141:        if (idx >= ARRAY_LENGTH(&paste_buffers))
1.1       nicm      142:                return (-1);
                    143:
1.18    ! nicm      144:        pb = ARRAY_ITEM(&paste_buffers, idx);
1.12      nicm      145:        free(pb->data);
1.1       nicm      146:
                    147:        pb->data = data;
1.4       nicm      148:        pb->size = size;
1.1       nicm      149:
                    150:        return (0);
1.9       nicm      151: }
                    152:
1.17      nicm      153: /* Convert start of buffer into a nice string. */
1.9       nicm      154: char *
1.17      nicm      155: paste_make_sample(struct paste_buffer *pb, int utf8flag)
1.9       nicm      156: {
1.17      nicm      157:        char            *buf;
                    158:        size_t           len, used;
                    159:        const int        flags = VIS_OCTAL|VIS_TAB|VIS_NL;
                    160:        const size_t     width = 200;
1.9       nicm      161:
                    162:        len = pb->size;
                    163:        if (len > width)
                    164:                len = width;
1.17      nicm      165:        buf = xmalloc(len * 4 + 4);
1.9       nicm      166:
1.17      nicm      167:        if (utf8flag)
                    168:                used = utf8_strvis(buf, pb->data, len, flags);
                    169:        else
                    170:                used = strvisx(buf, pb->data, len, flags);
1.13      nicm      171:        if (pb->size > width || used > width)
1.17      nicm      172:                strlcpy(buf + width, "...", 4);
1.9       nicm      173:        return (buf);
1.14      nicm      174: }
                    175:
                    176: /* Paste into a window pane, filtering '\n' according to separator. */
                    177: void
1.16      nicm      178: paste_send_pane(struct paste_buffer *pb, struct window_pane *wp,
1.14      nicm      179:     const char *sep, int bracket)
                    180: {
                    181:        const char      *data = pb->data, *end = data + pb->size, *lf;
                    182:        size_t           seplen;
                    183:
                    184:        if (bracket)
                    185:                bufferevent_write(wp->event, "\033[200~", 6);
                    186:
                    187:        seplen = strlen(sep);
                    188:        while ((lf = memchr(data, '\n', end - data)) != NULL) {
                    189:                if (lf != data)
                    190:                        bufferevent_write(wp->event, data, lf - data);
                    191:                bufferevent_write(wp->event, sep, seplen);
                    192:                data = lf + 1;
                    193:        }
                    194:
                    195:        if (end != data)
                    196:                bufferevent_write(wp->event, data, end - data);
                    197:
                    198:        if (bracket)
                    199:                bufferevent_write(wp->event, "\033[201~", 6);
1.1       nicm      200: }