Annotation of src/usr.bin/tmux/paste.c, Revision 1.10
1.10 ! nicm 1: /* $OpenBSD: paste.c,v 1.9 2010/06/21 21:44:09 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:
22: #include <string.h>
1.9 nicm 23: #include <vis.h>
1.1 nicm 24:
25: #include "tmux.h"
26:
1.7 nicm 27: /*
28: * Stack of paste buffers. Note that paste buffer data is not necessarily a C
29: * string!
30: */
1.1 nicm 31:
1.7 nicm 32: /* Return each item of the stack in turn. */
1.1 nicm 33: struct paste_buffer *
34: paste_walk_stack(struct paste_stack *ps, uint *idx)
35: {
36: struct paste_buffer *pb;
37:
38: pb = paste_get_index(ps, *idx);
39: (*idx)++;
40: return (pb);
41: }
42:
1.7 nicm 43: /* Get the top item on the stack. */
1.1 nicm 44: struct paste_buffer *
45: paste_get_top(struct paste_stack *ps)
46: {
47: if (ARRAY_LENGTH(ps) == 0)
48: return (NULL);
49: return (ARRAY_FIRST(ps));
50: }
51:
1.7 nicm 52: /* Get an item by its index. */
1.1 nicm 53: struct paste_buffer *
54: paste_get_index(struct paste_stack *ps, u_int idx)
55: {
56: if (idx >= ARRAY_LENGTH(ps))
57: return (NULL);
58: return (ARRAY_ITEM(ps, idx));
59: }
60:
1.7 nicm 61: /* Free the top item on the stack. */
1.1 nicm 62: int
63: paste_free_top(struct paste_stack *ps)
64: {
65: struct paste_buffer *pb;
66:
67: if (ARRAY_LENGTH(ps) == 0)
68: return (-1);
69:
70: pb = ARRAY_FIRST(ps);
71: ARRAY_REMOVE(ps, 0);
72:
73: xfree(pb->data);
74: xfree(pb);
75:
76: return (0);
77: }
78:
1.7 nicm 79: /* Free an item by index. */
1.1 nicm 80: int
81: paste_free_index(struct paste_stack *ps, u_int idx)
82: {
83: struct paste_buffer *pb;
84:
85: if (idx >= ARRAY_LENGTH(ps))
86: return (-1);
87:
88: pb = ARRAY_ITEM(ps, idx);
89: ARRAY_REMOVE(ps, idx);
90:
91: xfree(pb->data);
92: xfree(pb);
93:
94: return (0);
95: }
96:
1.8 nicm 97: /*
1.7 nicm 98: * Add an item onto the top of the stack, freeing the bottom if at limit. Note
99: * that the caller is responsible for allocating data.
100: */
1.1 nicm 101: void
1.7 nicm 102: paste_add(struct paste_stack *ps, char *data, size_t size, u_int limit)
1.1 nicm 103: {
104: struct paste_buffer *pb;
1.2 nicm 105:
1.7 nicm 106: if (size == 0)
1.2 nicm 107: return;
1.1 nicm 108:
1.3 nicm 109: while (ARRAY_LENGTH(ps) >= limit) {
110: pb = ARRAY_LAST(ps);
111: xfree(pb->data);
112: xfree(pb);
1.1 nicm 113: ARRAY_TRUNC(ps, 1);
1.3 nicm 114: }
1.1 nicm 115:
116: pb = xmalloc(sizeof *pb);
117: ARRAY_INSERT(ps, 0, pb);
118:
119: pb->data = data;
1.4 nicm 120: pb->size = size;
1.1 nicm 121: }
122:
1.7 nicm 123:
1.8 nicm 124: /*
1.7 nicm 125: * Replace an item on the stack. Note that the caller is responsible for
126: * allocating data.
127: */
1.1 nicm 128: int
1.7 nicm 129: paste_replace(struct paste_stack *ps, u_int idx, char *data, size_t size)
1.1 nicm 130: {
131: struct paste_buffer *pb;
1.7 nicm 132:
133: if (size == 0)
134: return (0);
1.1 nicm 135:
136: if (idx >= ARRAY_LENGTH(ps))
137: return (-1);
138:
139: pb = ARRAY_ITEM(ps, idx);
140: xfree(pb->data);
141:
142: pb->data = data;
1.4 nicm 143: pb->size = size;
1.1 nicm 144:
145: return (0);
1.9 nicm 146: }
147:
148: /* Convert a buffer into a visible string. */
149: char *
150: paste_print(struct paste_buffer *pb, size_t width)
151: {
152: char *buf;
153: size_t len, used;
154:
155: if (width < 3)
156: width = 3;
157: buf = xmalloc(width * 4 + 1);
158:
159: len = pb->size;
160: if (len > width)
161: len = width;
162:
163: used = strvisx(buf, pb->data, len, VIS_OCTAL|VIS_TAB|VIS_NL);
164: if (pb->size > width || used > width) {
165: buf[width - 3] = '\0';
166: strlcat(buf, "...", width);
167: }
168:
169: return (buf);
1.1 nicm 170: }