Annotation of src/usr.bin/tmux/cmd-copy-buffer.c, Revision 1.4
1.4 ! nicm 1: /* $OpenBSD: cmd-copy-buffer.c,v 1.3 2009/07/26 12:58:44 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
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:
1.4 ! nicm 19: #include <sys/types.h>
! 20:
1.1 nicm 21: #include <stdlib.h>
1.4 ! nicm 22: #include <string.h>
1.1 nicm 23:
24: #include "tmux.h"
25:
26: /*
27: * Copies a session paste buffer to another session.
28: */
29:
30: int cmd_copy_buffer_parse(struct cmd *, int, char **, char **);
31: int cmd_copy_buffer_exec(struct cmd *, struct cmd_ctx *);
32: void cmd_copy_buffer_free(struct cmd *);
33: void cmd_copy_buffer_init(struct cmd *, int);
34: size_t cmd_copy_buffer_print(struct cmd *, char *, size_t);
35:
36: struct cmd_copy_buffer_data {
37: char *dst_session;
38: char *src_session;
39: int dst_idx;
40: int src_idx;
41: };
42:
43: const struct cmd_entry cmd_copy_buffer_entry = {
44: "copy-buffer", "copyb",
45: "[-a src-index] [-b dst-index] [-s src-session] [-t dst-session]",
1.2 nicm 46: 0, 0,
1.1 nicm 47: cmd_copy_buffer_init,
48: cmd_copy_buffer_parse,
49: cmd_copy_buffer_exec,
50: cmd_copy_buffer_free,
51: cmd_copy_buffer_print
52: };
53:
54: void
55: cmd_copy_buffer_init(struct cmd *self, unused int arg)
56: {
57: struct cmd_copy_buffer_data *data;
58:
59: self->data = data = xmalloc(sizeof *data);
60: data->dst_session = NULL;
61: data->src_session = NULL;
62: data->dst_idx = -1;
63: data->src_idx = -1;
64: }
65:
66: int
67: cmd_copy_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
68: {
69: struct cmd_copy_buffer_data *data;
70: const char *errstr;
71: int n, opt;
72:
73: self->entry->init(self, 0);
74: data = self->data;
75:
76: while ((opt = getopt(argc, argv, "a:b:s:t:")) != -1) {
77: switch (opt) {
78: case 'a':
79: if (data->src_idx == -1) {
80: n = strtonum(optarg, 0, INT_MAX, &errstr);
81: if (errstr != NULL) {
82: xasprintf(cause, "buffer %s", errstr);
83: goto error;
84: }
85: data->src_idx = n;
86: }
87: break;
88: case 'b':
89: if (data->dst_idx == -1) {
90: n = strtonum(optarg, 0, INT_MAX, &errstr);
91: if (errstr != NULL) {
92: xasprintf(cause, "buffer %s", errstr);
93: goto error;
94: }
95: data->dst_idx = n;
96: }
97: break;
98: case 's':
99: if (data->src_session == NULL)
100: data->src_session = xstrdup(optarg);
101: break;
102: case 't':
103: if (data->dst_session == NULL)
104: data->dst_session = xstrdup(optarg);
105: break;
106: default:
107: goto usage;
108: }
109: }
110: argc -= optind;
111: argv += optind;
112:
113: return (0);
114:
115: usage:
116: xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
117:
118: error:
119: self->entry->free(self);
120: return (-1);
121: }
122:
123: int
124: cmd_copy_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
125: {
126: struct cmd_copy_buffer_data *data = self->data;
127: struct paste_buffer *pb;
1.4 ! nicm 128: struct paste_stack *dst_ps, *src_ps;
! 129: u_char *pdata;
1.1 nicm 130: struct session *dst_session, *src_session;
131: u_int limit;
132:
133: if ((dst_session = cmd_find_session(ctx, data->dst_session)) == NULL ||
134: (src_session = cmd_find_session(ctx, data->src_session)) == NULL)
135: return (-1);
1.4 ! nicm 136: dst_ps = &dst_session->buffers;
! 137: src_ps = &src_session->buffers;
1.1 nicm 138:
139: if (data->src_idx == -1) {
1.4 ! nicm 140: if ((pb = paste_get_top(src_ps)) == NULL) {
1.1 nicm 141: ctx->error(ctx, "no buffers");
142: return (-1);
143: }
144: } else {
1.4 ! nicm 145: if ((pb = paste_get_index(src_ps, data->src_idx)) == NULL) {
1.1 nicm 146: ctx->error(ctx, "no buffer %d", data->src_idx);
147: return (-1);
148: }
149: }
1.4 ! nicm 150: limit = options_get_number(&dst_session->options, "buffer-limit");
! 151:
! 152: pdata = xmalloc(pb->size);
! 153: memcpy(pdata, pb->data, pb->size);
1.1 nicm 154:
1.4 ! nicm 155: if (data->dst_idx == -1)
! 156: paste_add(dst_ps, pdata, pb->size, limit);
! 157: else if (paste_replace(dst_ps, data->dst_idx, pdata, pb->size) != 0) {
1.1 nicm 158: ctx->error(ctx, "no buffer %d", data->dst_idx);
1.4 ! nicm 159: xfree(pdata);
1.1 nicm 160: return (-1);
161: }
162:
163: return (0);
164: }
165:
166: void
167: cmd_copy_buffer_free(struct cmd *self)
168: {
169: struct cmd_copy_buffer_data *data = self->data;
170:
171: if (data->dst_session != NULL)
172: xfree(data->dst_session);
173: if (data->src_session != NULL)
174: xfree(data->src_session);
175: xfree(data);
176: }
177:
178: size_t
179: cmd_copy_buffer_print(struct cmd *self, char *buf, size_t len)
180: {
181: struct cmd_copy_buffer_data *data = self->data;
182: size_t off = 0;
183:
184: off += xsnprintf(buf, len, "%s", self->entry->name);
185: if (data == NULL)
186: return (off);
187: if (off < len && data->src_idx != -1) {
188: off += xsnprintf(buf + off, len - off, " -a %d",
189: data->src_idx);
190: }
191: if (off < len && data->dst_idx != -1) {
192: off += xsnprintf(buf + off, len - off, " -b %d",
193: data->dst_idx);
194: }
195: if (off < len && data->src_session != NULL) {
196: off += cmd_prarg(buf + off, len - off, " -s ",
197: data->src_session);
198: }
199: if (off < len && data->dst_session != NULL) {
200: off += cmd_prarg(buf + off, len - off, " -t ",
201: data->dst_session);
202: }
203: return (off);
204: }