1*eda6f593SDavid van Moolenbroek /* $Id: paste.c,v 1.1.1.2 2011/08/17 18:40:05 jmmv Exp $ */ 2*eda6f593SDavid van Moolenbroek 3*eda6f593SDavid van Moolenbroek /* 4*eda6f593SDavid van Moolenbroek * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> 5*eda6f593SDavid van Moolenbroek * 6*eda6f593SDavid van Moolenbroek * Permission to use, copy, modify, and distribute this software for any 7*eda6f593SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above 8*eda6f593SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies. 9*eda6f593SDavid van Moolenbroek * 10*eda6f593SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11*eda6f593SDavid van Moolenbroek * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12*eda6f593SDavid van Moolenbroek * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13*eda6f593SDavid van Moolenbroek * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14*eda6f593SDavid van Moolenbroek * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15*eda6f593SDavid van Moolenbroek * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16*eda6f593SDavid van Moolenbroek * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17*eda6f593SDavid van Moolenbroek */ 18*eda6f593SDavid van Moolenbroek 19*eda6f593SDavid van Moolenbroek #include <sys/types.h> 20*eda6f593SDavid van Moolenbroek #include <sys/time.h> 21*eda6f593SDavid van Moolenbroek 22*eda6f593SDavid van Moolenbroek #include <string.h> 23*eda6f593SDavid van Moolenbroek 24*eda6f593SDavid van Moolenbroek #include "tmux.h" 25*eda6f593SDavid van Moolenbroek 26*eda6f593SDavid van Moolenbroek /* 27*eda6f593SDavid van Moolenbroek * Stack of paste buffers. Note that paste buffer data is not necessarily a C 28*eda6f593SDavid van Moolenbroek * string! 29*eda6f593SDavid van Moolenbroek */ 30*eda6f593SDavid van Moolenbroek 31*eda6f593SDavid van Moolenbroek /* Return each item of the stack in turn. */ 32*eda6f593SDavid van Moolenbroek struct paste_buffer * 33*eda6f593SDavid van Moolenbroek paste_walk_stack(struct paste_stack *ps, u_int *idx) 34*eda6f593SDavid van Moolenbroek { 35*eda6f593SDavid van Moolenbroek struct paste_buffer *pb; 36*eda6f593SDavid van Moolenbroek 37*eda6f593SDavid van Moolenbroek pb = paste_get_index(ps, *idx); 38*eda6f593SDavid van Moolenbroek (*idx)++; 39*eda6f593SDavid van Moolenbroek return (pb); 40*eda6f593SDavid van Moolenbroek } 41*eda6f593SDavid van Moolenbroek 42*eda6f593SDavid van Moolenbroek /* Get the top item on the stack. */ 43*eda6f593SDavid van Moolenbroek struct paste_buffer * 44*eda6f593SDavid van Moolenbroek paste_get_top(struct paste_stack *ps) 45*eda6f593SDavid van Moolenbroek { 46*eda6f593SDavid van Moolenbroek if (ARRAY_LENGTH(ps) == 0) 47*eda6f593SDavid van Moolenbroek return (NULL); 48*eda6f593SDavid van Moolenbroek return (ARRAY_FIRST(ps)); 49*eda6f593SDavid van Moolenbroek } 50*eda6f593SDavid van Moolenbroek 51*eda6f593SDavid van Moolenbroek /* Get an item by its index. */ 52*eda6f593SDavid van Moolenbroek struct paste_buffer * 53*eda6f593SDavid van Moolenbroek paste_get_index(struct paste_stack *ps, u_int idx) 54*eda6f593SDavid van Moolenbroek { 55*eda6f593SDavid van Moolenbroek if (idx >= ARRAY_LENGTH(ps)) 56*eda6f593SDavid van Moolenbroek return (NULL); 57*eda6f593SDavid van Moolenbroek return (ARRAY_ITEM(ps, idx)); 58*eda6f593SDavid van Moolenbroek } 59*eda6f593SDavid van Moolenbroek 60*eda6f593SDavid van Moolenbroek /* Free the top item on the stack. */ 61*eda6f593SDavid van Moolenbroek int 62*eda6f593SDavid van Moolenbroek paste_free_top(struct paste_stack *ps) 63*eda6f593SDavid van Moolenbroek { 64*eda6f593SDavid van Moolenbroek struct paste_buffer *pb; 65*eda6f593SDavid van Moolenbroek 66*eda6f593SDavid van Moolenbroek if (ARRAY_LENGTH(ps) == 0) 67*eda6f593SDavid van Moolenbroek return (-1); 68*eda6f593SDavid van Moolenbroek 69*eda6f593SDavid van Moolenbroek pb = ARRAY_FIRST(ps); 70*eda6f593SDavid van Moolenbroek ARRAY_REMOVE(ps, 0); 71*eda6f593SDavid van Moolenbroek 72*eda6f593SDavid van Moolenbroek xfree(pb->data); 73*eda6f593SDavid van Moolenbroek xfree(pb); 74*eda6f593SDavid van Moolenbroek 75*eda6f593SDavid van Moolenbroek return (0); 76*eda6f593SDavid van Moolenbroek } 77*eda6f593SDavid van Moolenbroek 78*eda6f593SDavid van Moolenbroek /* Free an item by index. */ 79*eda6f593SDavid van Moolenbroek int 80*eda6f593SDavid van Moolenbroek paste_free_index(struct paste_stack *ps, u_int idx) 81*eda6f593SDavid van Moolenbroek { 82*eda6f593SDavid van Moolenbroek struct paste_buffer *pb; 83*eda6f593SDavid van Moolenbroek 84*eda6f593SDavid van Moolenbroek if (idx >= ARRAY_LENGTH(ps)) 85*eda6f593SDavid van Moolenbroek return (-1); 86*eda6f593SDavid van Moolenbroek 87*eda6f593SDavid van Moolenbroek pb = ARRAY_ITEM(ps, idx); 88*eda6f593SDavid van Moolenbroek ARRAY_REMOVE(ps, idx); 89*eda6f593SDavid van Moolenbroek 90*eda6f593SDavid van Moolenbroek xfree(pb->data); 91*eda6f593SDavid van Moolenbroek xfree(pb); 92*eda6f593SDavid van Moolenbroek 93*eda6f593SDavid van Moolenbroek return (0); 94*eda6f593SDavid van Moolenbroek } 95*eda6f593SDavid van Moolenbroek 96*eda6f593SDavid van Moolenbroek /* 97*eda6f593SDavid van Moolenbroek * Add an item onto the top of the stack, freeing the bottom if at limit. Note 98*eda6f593SDavid van Moolenbroek * that the caller is responsible for allocating data. 99*eda6f593SDavid van Moolenbroek */ 100*eda6f593SDavid van Moolenbroek void 101*eda6f593SDavid van Moolenbroek paste_add(struct paste_stack *ps, char *data, size_t size, u_int limit) 102*eda6f593SDavid van Moolenbroek { 103*eda6f593SDavid van Moolenbroek struct paste_buffer *pb; 104*eda6f593SDavid van Moolenbroek 105*eda6f593SDavid van Moolenbroek if (size == 0) 106*eda6f593SDavid van Moolenbroek return; 107*eda6f593SDavid van Moolenbroek 108*eda6f593SDavid van Moolenbroek while (ARRAY_LENGTH(ps) >= limit) { 109*eda6f593SDavid van Moolenbroek pb = ARRAY_LAST(ps); 110*eda6f593SDavid van Moolenbroek xfree(pb->data); 111*eda6f593SDavid van Moolenbroek xfree(pb); 112*eda6f593SDavid van Moolenbroek ARRAY_TRUNC(ps, 1); 113*eda6f593SDavid van Moolenbroek } 114*eda6f593SDavid van Moolenbroek 115*eda6f593SDavid van Moolenbroek pb = xmalloc(sizeof *pb); 116*eda6f593SDavid van Moolenbroek ARRAY_INSERT(ps, 0, pb); 117*eda6f593SDavid van Moolenbroek 118*eda6f593SDavid van Moolenbroek pb->data = data; 119*eda6f593SDavid van Moolenbroek pb->size = size; 120*eda6f593SDavid van Moolenbroek } 121*eda6f593SDavid van Moolenbroek 122*eda6f593SDavid van Moolenbroek 123*eda6f593SDavid van Moolenbroek /* 124*eda6f593SDavid van Moolenbroek * Replace an item on the stack. Note that the caller is responsible for 125*eda6f593SDavid van Moolenbroek * allocating data. 126*eda6f593SDavid van Moolenbroek */ 127*eda6f593SDavid van Moolenbroek int 128*eda6f593SDavid van Moolenbroek paste_replace(struct paste_stack *ps, u_int idx, char *data, size_t size) 129*eda6f593SDavid van Moolenbroek { 130*eda6f593SDavid van Moolenbroek struct paste_buffer *pb; 131*eda6f593SDavid van Moolenbroek 132*eda6f593SDavid van Moolenbroek if (size == 0) 133*eda6f593SDavid van Moolenbroek return (0); 134*eda6f593SDavid van Moolenbroek 135*eda6f593SDavid van Moolenbroek if (idx >= ARRAY_LENGTH(ps)) 136*eda6f593SDavid van Moolenbroek return (-1); 137*eda6f593SDavid van Moolenbroek 138*eda6f593SDavid van Moolenbroek pb = ARRAY_ITEM(ps, idx); 139*eda6f593SDavid van Moolenbroek xfree(pb->data); 140*eda6f593SDavid van Moolenbroek 141*eda6f593SDavid van Moolenbroek pb->data = data; 142*eda6f593SDavid van Moolenbroek pb->size = size; 143*eda6f593SDavid van Moolenbroek 144*eda6f593SDavid van Moolenbroek return (0); 145*eda6f593SDavid van Moolenbroek } 146*eda6f593SDavid van Moolenbroek 147*eda6f593SDavid van Moolenbroek /* Convert a buffer into a visible string. */ 148*eda6f593SDavid van Moolenbroek char * 149*eda6f593SDavid van Moolenbroek paste_print(struct paste_buffer *pb, size_t width) 150*eda6f593SDavid van Moolenbroek { 151*eda6f593SDavid van Moolenbroek char *buf; 152*eda6f593SDavid van Moolenbroek size_t len, used; 153*eda6f593SDavid van Moolenbroek 154*eda6f593SDavid van Moolenbroek if (width < 3) 155*eda6f593SDavid van Moolenbroek width = 3; 156*eda6f593SDavid van Moolenbroek buf = xmalloc(width * 4 + 1); 157*eda6f593SDavid van Moolenbroek 158*eda6f593SDavid van Moolenbroek len = pb->size; 159*eda6f593SDavid van Moolenbroek if (len > width) 160*eda6f593SDavid van Moolenbroek len = width; 161*eda6f593SDavid van Moolenbroek 162*eda6f593SDavid van Moolenbroek used = strvisx(buf, pb->data, len, VIS_OCTAL|VIS_TAB|VIS_NL); 163*eda6f593SDavid van Moolenbroek if (pb->size > width || used > width) { 164*eda6f593SDavid van Moolenbroek buf[width - 3] = '\0'; 165*eda6f593SDavid van Moolenbroek strlcat(buf, "...", width); 166*eda6f593SDavid van Moolenbroek } 167*eda6f593SDavid van Moolenbroek 168*eda6f593SDavid van Moolenbroek return (buf); 169*eda6f593SDavid van Moolenbroek } 170