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