[BACK]Return to cmd-generic.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/cmd-generic.c, Revision 1.1

1.1     ! nicm        1: /* $OpenBSD$ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2008 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:
        !            21: #include <stdlib.h>
        !            22: #include <string.h>
        !            23:
        !            24: #include "tmux.h"
        !            25:
        !            26: #define CMD_FLAGS "adDgkuU"
        !            27: #define CMD_FLAGMASK (CMD_AFLAG|CMD_DFLAG|CMD_BIGDFLAG|CMD_GFLAG|CMD_KFLAG| \
        !            28:     CMD_UFLAG|CMD_BIGUFLAG)
        !            29:
        !            30: int    cmd_do_flags(int, int, int *);
        !            31: size_t cmd_print_flags(char *, size_t, size_t, int);
        !            32: int    cmd_fill_argument(int, char **, int, char **);
        !            33:
        !            34: size_t
        !            35: cmd_prarg(char *buf, size_t len, const char *prefix, char *arg)
        !            36: {
        !            37:        if (strchr(arg, ' ') != NULL)
        !            38:                return (xsnprintf(buf, len, "%s\"%s\"", prefix, arg));
        !            39:        return (xsnprintf(buf, len, "%s%s", prefix, arg));
        !            40: }
        !            41:
        !            42: int
        !            43: cmd_do_flags(int opt, int iflags, int *oflags)
        !            44: {
        !            45:        switch (opt) {
        !            46:        case 'a':
        !            47:                if (iflags & CMD_AFLAG) {
        !            48:                        (*oflags) |= CMD_AFLAG;
        !            49:                        return (0);
        !            50:                }
        !            51:                return (-1);
        !            52:        case 'd':
        !            53:                if (iflags & CMD_DFLAG) {
        !            54:                        (*oflags) |= CMD_DFLAG;
        !            55:                        return (0);
        !            56:                }
        !            57:                return (-1);
        !            58:        case 'D':
        !            59:                if (iflags & CMD_BIGDFLAG) {
        !            60:                        (*oflags) |= CMD_BIGDFLAG;
        !            61:                        return (0);
        !            62:                }
        !            63:                return (-1);
        !            64:        case 'g':
        !            65:                if (iflags & CMD_GFLAG) {
        !            66:                        (*oflags) |= CMD_GFLAG;
        !            67:                        return (0);
        !            68:                }
        !            69:                return (-1);
        !            70:        case 'k':
        !            71:                if (iflags & CMD_KFLAG) {
        !            72:                        (*oflags) |= CMD_KFLAG;
        !            73:                        return (0);
        !            74:                }
        !            75:                return (-1);
        !            76:        case 'u':
        !            77:                if (iflags & CMD_UFLAG) {
        !            78:                        (*oflags) |= CMD_UFLAG;
        !            79:                        return (0);
        !            80:                }
        !            81:                return (-1);
        !            82:        case 'U':
        !            83:                if (iflags & CMD_BIGUFLAG) {
        !            84:                        (*oflags) |= CMD_BIGUFLAG;
        !            85:                        return (0);
        !            86:                }
        !            87:                return (-1);
        !            88:        }
        !            89:        return (1);
        !            90: }
        !            91:
        !            92: size_t
        !            93: cmd_print_flags(char *buf, size_t len, size_t off, int flags)
        !            94: {
        !            95:        size_t  boff = off;
        !            96:
        !            97:        if ((flags & CMD_FLAGMASK) == 0)
        !            98:                return (0);
        !            99:        off += xsnprintf(buf + off, len - off, " -");
        !           100:        if (off < len && flags & CMD_AFLAG)
        !           101:                off += xsnprintf(buf + off, len - off, "a");
        !           102:        if (off < len && flags & CMD_BIGDFLAG)
        !           103:                off += xsnprintf(buf + off, len - off, "D");
        !           104:        if (off < len && flags & CMD_DFLAG)
        !           105:                off += xsnprintf(buf + off, len - off, "d");
        !           106:        if (off < len && flags & CMD_GFLAG)
        !           107:                off += xsnprintf(buf + off, len - off, "g");
        !           108:        if (off < len && flags & CMD_KFLAG)
        !           109:                off += xsnprintf(buf + off, len - off, "k");
        !           110:        if (off < len && flags & CMD_UFLAG)
        !           111:                off += xsnprintf(buf + off, len - off, "u");
        !           112:        if (off < len && flags & CMD_BIGUFLAG)
        !           113:                off += xsnprintf(buf + off, len - off, "U");
        !           114:        return (off - boff);
        !           115: }
        !           116:
        !           117: int
        !           118: cmd_fill_argument(int flags, char **arg, int argc, char **argv)
        !           119: {
        !           120:        *arg = NULL;
        !           121:
        !           122:        if (flags & CMD_ARG1) {
        !           123:                if (argc != 1)
        !           124:                        return (-1);
        !           125:                *arg = xstrdup(argv[0]);
        !           126:                return (0);
        !           127:        }
        !           128:
        !           129:        if (flags & CMD_ARG01) {
        !           130:                if (argc != 0 && argc != 1)
        !           131:                        return (-1);
        !           132:                if (argc == 1)
        !           133:                        *arg = xstrdup(argv[0]);
        !           134:                return (0);
        !           135:        }
        !           136:
        !           137:        if (argc != 0)
        !           138:                return (-1);
        !           139:        return (0);
        !           140: }
        !           141:
        !           142: void
        !           143: cmd_target_init(struct cmd *self, unused int key)
        !           144: {
        !           145:        struct cmd_target_data  *data;
        !           146:
        !           147:        self->data = data = xmalloc(sizeof *data);
        !           148:        data->flags = 0;
        !           149:        data->target = NULL;
        !           150:        data->arg = NULL;
        !           151: }
        !           152:
        !           153: int
        !           154: cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
        !           155: {
        !           156:        struct cmd_target_data  *data;
        !           157:        int                      opt;
        !           158:
        !           159:        /* Don't use the entry version since it may be dependent on key. */
        !           160:        cmd_target_init(self, 0);
        !           161:        data = self->data;
        !           162:
        !           163:        while ((opt = getopt(argc, argv, CMD_FLAGS "t:")) != -1) {
        !           164:                switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
        !           165:                case -1:
        !           166:                        goto usage;
        !           167:                case 0:
        !           168:                        continue;
        !           169:                }
        !           170:                switch (opt) {
        !           171:                case 't':
        !           172:                        if (data->target == NULL)
        !           173:                                data->target = xstrdup(optarg);
        !           174:                        break;
        !           175:                default:
        !           176:                        goto usage;
        !           177:                }
        !           178:        }
        !           179:        argc -= optind;
        !           180:        argv += optind;
        !           181:
        !           182:        if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
        !           183:                goto usage;
        !           184:        return (0);
        !           185:
        !           186: usage:
        !           187:        xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
        !           188:
        !           189:        self->entry->free(self);
        !           190:        return (-1);
        !           191: }
        !           192:
        !           193: void
        !           194: cmd_target_send(struct cmd *self, struct buffer *b)
        !           195: {
        !           196:        struct cmd_target_data  *data = self->data;
        !           197:
        !           198:        buffer_write(b, data, sizeof *data);
        !           199:        cmd_send_string(b, data->target);
        !           200:        cmd_send_string(b, data->arg);
        !           201: }
        !           202:
        !           203: void
        !           204: cmd_target_recv(struct cmd *self, struct buffer *b)
        !           205: {
        !           206:        struct cmd_target_data  *data;
        !           207:
        !           208:        self->data = data = xmalloc(sizeof *data);
        !           209:        buffer_read(b, data, sizeof *data);
        !           210:        data->target = cmd_recv_string(b);
        !           211:        data->arg = cmd_recv_string(b);
        !           212: }
        !           213:
        !           214: void
        !           215: cmd_target_free(struct cmd *self)
        !           216: {
        !           217:        struct cmd_target_data  *data = self->data;
        !           218:
        !           219:        if (data->target != NULL)
        !           220:                xfree(data->target);
        !           221:        if (data->arg != NULL)
        !           222:                xfree(data->arg);
        !           223:        xfree(data);
        !           224: }
        !           225:
        !           226: size_t
        !           227: cmd_target_print(struct cmd *self, char *buf, size_t len)
        !           228: {
        !           229:        struct cmd_target_data  *data = self->data;
        !           230:        size_t                   off = 0;
        !           231:
        !           232:        off += xsnprintf(buf, len, "%s", self->entry->name);
        !           233:        if (data == NULL)
        !           234:                return (off);
        !           235:        off += cmd_print_flags(buf, len, off, data->flags);
        !           236:        if (off < len && data->target != NULL)
        !           237:                off += cmd_prarg(buf + off, len - off, " -t ", data->target);
        !           238:        if (off < len && data->arg != NULL)
        !           239:                off += cmd_prarg(buf + off, len - off, " ", data->arg);
        !           240:        return (off);
        !           241: }
        !           242:
        !           243: void
        !           244: cmd_srcdst_init(struct cmd *self, unused int key)
        !           245: {
        !           246:        struct cmd_srcdst_data  *data;
        !           247:
        !           248:        self->data = data = xmalloc(sizeof *data);
        !           249:        data->flags = 0;
        !           250:        data->src = NULL;
        !           251:        data->dst = NULL;
        !           252:        data->arg = NULL;
        !           253: }
        !           254:
        !           255: int
        !           256: cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
        !           257: {
        !           258:        struct cmd_srcdst_data  *data;
        !           259:        int                      opt;
        !           260:
        !           261:        cmd_srcdst_init(self, 0);
        !           262:        data = self->data;
        !           263:
        !           264:        while ((opt = getopt(argc, argv, CMD_FLAGS "s:t:")) != -1) {
        !           265:                switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
        !           266:                case -1:
        !           267:                        goto usage;
        !           268:                case 0:
        !           269:                        continue;
        !           270:                }
        !           271:                switch (opt) {
        !           272:                case 's':
        !           273:                        if (data->src == NULL)
        !           274:                                data->src = xstrdup(optarg);
        !           275:                        break;
        !           276:                case 't':
        !           277:                        if (data->dst == NULL)
        !           278:                                data->dst = xstrdup(optarg);
        !           279:                        break;
        !           280:                default:
        !           281:                        goto usage;
        !           282:                }
        !           283:        }
        !           284:        argc -= optind;
        !           285:        argv += optind;
        !           286:
        !           287:        if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
        !           288:                goto usage;
        !           289:        return (0);
        !           290:
        !           291: usage:
        !           292:        xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
        !           293:
        !           294:        self->entry->free(self);
        !           295:        return (-1);
        !           296: }
        !           297:
        !           298: void
        !           299: cmd_srcdst_send(struct cmd *self, struct buffer *b)
        !           300: {
        !           301:        struct cmd_srcdst_data  *data = self->data;
        !           302:
        !           303:        buffer_write(b, data, sizeof *data);
        !           304:        cmd_send_string(b, data->src);
        !           305:        cmd_send_string(b, data->dst);
        !           306:        cmd_send_string(b, data->arg);
        !           307: }
        !           308:
        !           309: void
        !           310: cmd_srcdst_recv(struct cmd *self, struct buffer *b)
        !           311: {
        !           312:        struct cmd_srcdst_data  *data;
        !           313:
        !           314:        self->data = data = xmalloc(sizeof *data);
        !           315:        buffer_read(b, data, sizeof *data);
        !           316:        data->src = cmd_recv_string(b);
        !           317:        data->dst = cmd_recv_string(b);
        !           318:        data->arg = cmd_recv_string(b);
        !           319: }
        !           320:
        !           321: void
        !           322: cmd_srcdst_free(struct cmd *self)
        !           323: {
        !           324:        struct cmd_srcdst_data  *data = self->data;
        !           325:
        !           326:        if (data->src != NULL)
        !           327:                xfree(data->src);
        !           328:        if (data->dst != NULL)
        !           329:                xfree(data->dst);
        !           330:        if (data->arg != NULL)
        !           331:                xfree(data->arg);
        !           332:        xfree(data);
        !           333: }
        !           334:
        !           335: size_t
        !           336: cmd_srcdst_print(struct cmd *self, char *buf, size_t len)
        !           337: {
        !           338:        struct cmd_srcdst_data  *data = self->data;
        !           339:        size_t                   off = 0;
        !           340:
        !           341:        off += xsnprintf(buf, len, "%s", self->entry->name);
        !           342:        if (data == NULL)
        !           343:                return (off);
        !           344:        off += cmd_print_flags(buf, len, off, data->flags);
        !           345:        if (off < len && data->src != NULL)
        !           346:                off += xsnprintf(buf + off, len - off, " -s %s", data->src);
        !           347:        if (off < len && data->dst != NULL)
        !           348:                off += xsnprintf(buf + off, len - off, " -t %s", data->dst);
        !           349:        if (off < len && data->arg != NULL)
        !           350:                off += cmd_prarg(buf + off, len - off, " ", data->arg);
        !           351:        return (off);
        !           352: }
        !           353:
        !           354: void
        !           355: cmd_buffer_init(struct cmd *self, unused int key)
        !           356: {
        !           357:        struct cmd_buffer_data  *data;
        !           358:
        !           359:        self->data = data = xmalloc(sizeof *data);
        !           360:        data->flags = 0;
        !           361:        data->target = NULL;
        !           362:        data->buffer = -1;
        !           363:        data->arg = NULL;
        !           364: }
        !           365:
        !           366: int
        !           367: cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
        !           368: {
        !           369:        struct cmd_buffer_data  *data;
        !           370:        int                      opt, n;
        !           371:        const char              *errstr;
        !           372:
        !           373:        cmd_buffer_init(self, 0);
        !           374:        data = self->data;
        !           375:
        !           376:        while ((opt = getopt(argc, argv, CMD_FLAGS "b:t:")) != -1) {
        !           377:                switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
        !           378:                case -1:
        !           379:                        goto usage;
        !           380:                case 0:
        !           381:                        continue;
        !           382:                }
        !           383:                switch (opt) {
        !           384:                case 'b':
        !           385:                        if (data->buffer == -1) {
        !           386:                                n = strtonum(optarg, 0, INT_MAX, &errstr);
        !           387:                                if (errstr != NULL) {
        !           388:                                        xasprintf(cause, "buffer %s", errstr);
        !           389:                                        goto error;
        !           390:                                }
        !           391:                                data->buffer = n;
        !           392:                        }
        !           393:                        break;
        !           394:                case 't':
        !           395:                        if (data->target == NULL)
        !           396:                                data->target = xstrdup(optarg);
        !           397:                        break;
        !           398:                default:
        !           399:                        goto usage;
        !           400:                }
        !           401:        }
        !           402:        argc -= optind;
        !           403:        argv += optind;
        !           404:
        !           405:        if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
        !           406:                goto usage;
        !           407:        return (0);
        !           408:
        !           409: usage:
        !           410:        xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
        !           411:
        !           412: error:
        !           413:        self->entry->free(self);
        !           414:        return (-1);
        !           415: }
        !           416:
        !           417: void
        !           418: cmd_buffer_send(struct cmd *self, struct buffer *b)
        !           419: {
        !           420:        struct cmd_buffer_data  *data = self->data;
        !           421:
        !           422:        buffer_write(b, data, sizeof *data);
        !           423:        cmd_send_string(b, data->target);
        !           424:        cmd_send_string(b, data->arg);
        !           425: }
        !           426:
        !           427: void
        !           428: cmd_buffer_recv(struct cmd *self, struct buffer *b)
        !           429: {
        !           430:        struct cmd_buffer_data  *data;
        !           431:
        !           432:        self->data = data = xmalloc(sizeof *data);
        !           433:        buffer_read(b, data, sizeof *data);
        !           434:        data->target = cmd_recv_string(b);
        !           435:        data->arg = cmd_recv_string(b);
        !           436: }
        !           437:
        !           438: void
        !           439: cmd_buffer_free(struct cmd *self)
        !           440: {
        !           441:        struct cmd_buffer_data  *data = self->data;
        !           442:
        !           443:        if (data->target != NULL)
        !           444:                xfree(data->target);
        !           445:        if (data->arg != NULL)
        !           446:                xfree(data->arg);
        !           447:        xfree(data);
        !           448: }
        !           449:
        !           450: size_t
        !           451: cmd_buffer_print(struct cmd *self, char *buf, size_t len)
        !           452: {
        !           453:        struct cmd_buffer_data  *data = self->data;
        !           454:        size_t                   off = 0;
        !           455:
        !           456:        off += xsnprintf(buf, len, "%s", self->entry->name);
        !           457:        if (data == NULL)
        !           458:                return (off);
        !           459:        off += cmd_print_flags(buf, len, off, data->flags);
        !           460:        if (off < len && data->buffer != -1)
        !           461:                off += xsnprintf(buf + off, len - off, " -b %d", data->buffer);
        !           462:        if (off < len && data->target != NULL)
        !           463:                off += cmd_prarg(buf + off, len - off, " -t ", data->target);
        !           464:        if (off < len && data->arg != NULL)
        !           465:                off += cmd_prarg(buf + off, len - off, " ", data->arg);
        !           466:        return (off);
        !           467: }
        !           468:
        !           469: void
        !           470: cmd_option_init(struct cmd *self, unused int key)
        !           471: {
        !           472:        struct cmd_option_data  *data;
        !           473:
        !           474:        self->data = data = xmalloc(sizeof *data);
        !           475:        data->flags = 0;
        !           476:        data->target = NULL;
        !           477:        data->option = NULL;
        !           478:        data->value = NULL;
        !           479: }
        !           480:
        !           481: int
        !           482: cmd_option_parse(struct cmd *self, int argc, char **argv, char **cause)
        !           483: {
        !           484:        struct cmd_option_data  *data;
        !           485:        int                      opt;
        !           486:
        !           487:        /* Don't use the entry version since it may be dependent on key. */
        !           488:        cmd_option_init(self, 0);
        !           489:        data = self->data;
        !           490:
        !           491:        while ((opt = getopt(argc, argv, CMD_FLAGS "t:")) != -1) {
        !           492:                switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
        !           493:                case -1:
        !           494:                        goto usage;
        !           495:                case 0:
        !           496:                        continue;
        !           497:                }
        !           498:                switch (opt) {
        !           499:                case 't':
        !           500:                        if (data->target == NULL)
        !           501:                                data->target = xstrdup(optarg);
        !           502:                        break;
        !           503:                default:
        !           504:                        goto usage;
        !           505:                }
        !           506:        }
        !           507:        argc -= optind;
        !           508:        argv += optind;
        !           509:
        !           510:        if (argc == 2) {
        !           511:                data->option = xstrdup(argv[0]);
        !           512:                data->value = xstrdup(argv[1]);
        !           513:        } else if (argc == 1)
        !           514:                data->option = xstrdup(argv[0]);
        !           515:        else
        !           516:                goto usage;
        !           517:        return (0);
        !           518:
        !           519: usage:
        !           520:        xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
        !           521:
        !           522:        self->entry->free(self);
        !           523:        return (-1);
        !           524: }
        !           525:
        !           526: void
        !           527: cmd_option_send(struct cmd *self, struct buffer *b)
        !           528: {
        !           529:        struct cmd_option_data  *data = self->data;
        !           530:
        !           531:        buffer_write(b, data, sizeof *data);
        !           532:        cmd_send_string(b, data->target);
        !           533:        cmd_send_string(b, data->option);
        !           534:        cmd_send_string(b, data->value);
        !           535: }
        !           536:
        !           537: void
        !           538: cmd_option_recv(struct cmd *self, struct buffer *b)
        !           539: {
        !           540:        struct cmd_option_data  *data;
        !           541:
        !           542:        self->data = data = xmalloc(sizeof *data);
        !           543:        buffer_read(b, data, sizeof *data);
        !           544:        data->target = cmd_recv_string(b);
        !           545:        data->option = cmd_recv_string(b);
        !           546:        data->value = cmd_recv_string(b);
        !           547: }
        !           548:
        !           549: void
        !           550: cmd_option_free(struct cmd *self)
        !           551: {
        !           552:        struct cmd_option_data  *data = self->data;
        !           553:
        !           554:        if (data->target != NULL)
        !           555:                xfree(data->target);
        !           556:        if (data->option != NULL)
        !           557:                xfree(data->option);
        !           558:        if (data->value != NULL)
        !           559:                xfree(data->value);
        !           560:        xfree(data);
        !           561: }
        !           562:
        !           563: size_t
        !           564: cmd_option_print(struct cmd *self, char *buf, size_t len)
        !           565: {
        !           566:        struct cmd_option_data  *data = self->data;
        !           567:        size_t                   off = 0;
        !           568:
        !           569:        off += xsnprintf(buf, len, "%s", self->entry->name);
        !           570:        if (data == NULL)
        !           571:                return (off);
        !           572:        off += cmd_print_flags(buf, len, off, data->flags);
        !           573:        if (off < len && data->target != NULL)
        !           574:                off += cmd_prarg(buf + off, len - off, " -t ", data->target);
        !           575:        if (off < len && data->option != NULL)
        !           576:                off += xsnprintf(buf + off, len - off, " %s", data->option);
        !           577:        if (off < len && data->value != NULL)
        !           578:                off += xsnprintf(buf + off, len - off, " %s", data->value);
        !           579:        return (off);
        !           580: }
        !           581:
        !           582: void
        !           583: cmd_pane_init(struct cmd *self, unused int key)
        !           584: {
        !           585:        struct cmd_pane_data    *data;
        !           586:
        !           587:        self->data = data = xmalloc(sizeof *data);
        !           588:        data->flags = 0;
        !           589:        data->target = NULL;
        !           590:        data->arg = NULL;
        !           591:        data->pane = -1;
        !           592: }
        !           593:
        !           594: int
        !           595: cmd_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
        !           596: {
        !           597:        struct cmd_pane_data    *data;
        !           598:        int                      opt, n;
        !           599:        const char              *errstr;
        !           600:
        !           601:        /* Don't use the entry version since it may be dependent on key. */
        !           602:        cmd_pane_init(self, 0);
        !           603:        data = self->data;
        !           604:
        !           605:        while ((opt = getopt(argc, argv, CMD_FLAGS "p:t:")) != -1) {
        !           606:                switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
        !           607:                case -1:
        !           608:                        goto usage;
        !           609:                case 0:
        !           610:                        continue;
        !           611:                }
        !           612:                switch (opt) {
        !           613:                case 'p':
        !           614:                        if (data->pane == -1) {
        !           615:                                n = strtonum(optarg, 0, INT_MAX, &errstr);
        !           616:                                if (errstr != NULL) {
        !           617:                                        xasprintf(cause, "pane %s", errstr);
        !           618:                                        goto error;
        !           619:                                }
        !           620:                                data->pane = n;
        !           621:                        }
        !           622:                        break;
        !           623:                case 't':
        !           624:                        if (data->target == NULL)
        !           625:                                data->target = xstrdup(optarg);
        !           626:                        break;
        !           627:                default:
        !           628:                        goto usage;
        !           629:                }
        !           630:        }
        !           631:        argc -= optind;
        !           632:        argv += optind;
        !           633:
        !           634:        if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
        !           635:                goto usage;
        !           636:        return (0);
        !           637:
        !           638: usage:
        !           639:        xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
        !           640:
        !           641: error:
        !           642:        self->entry->free(self);
        !           643:        return (-1);
        !           644: }
        !           645:
        !           646: void
        !           647: cmd_pane_send(struct cmd *self, struct buffer *b)
        !           648: {
        !           649:        struct cmd_pane_data    *data = self->data;
        !           650:
        !           651:        buffer_write(b, data, sizeof *data);
        !           652:        cmd_send_string(b, data->target);
        !           653:        cmd_send_string(b, data->arg);
        !           654: }
        !           655:
        !           656: void
        !           657: cmd_pane_recv(struct cmd *self, struct buffer *b)
        !           658: {
        !           659:        struct cmd_pane_data    *data;
        !           660:
        !           661:        self->data = data = xmalloc(sizeof *data);
        !           662:        buffer_read(b, data, sizeof *data);
        !           663:        data->target = cmd_recv_string(b);
        !           664:        data->arg = cmd_recv_string(b);
        !           665: }
        !           666:
        !           667: void
        !           668: cmd_pane_free(struct cmd *self)
        !           669: {
        !           670:        struct cmd_pane_data    *data = self->data;
        !           671:
        !           672:        if (data->target != NULL)
        !           673:                xfree(data->target);
        !           674:        if (data->arg != NULL)
        !           675:                xfree(data->arg);
        !           676:        xfree(data);
        !           677: }
        !           678:
        !           679: size_t
        !           680: cmd_pane_print(struct cmd *self, char *buf, size_t len)
        !           681: {
        !           682:        struct cmd_pane_data    *data = self->data;
        !           683:        size_t                   off = 0;
        !           684:
        !           685:        off += xsnprintf(buf, len, "%s", self->entry->name);
        !           686:        if (data == NULL)
        !           687:                return (off);
        !           688:        off += cmd_print_flags(buf, len, off, data->flags);
        !           689:        if (off < len && data->target != NULL)
        !           690:                off += cmd_prarg(buf + off, len - off, " -t ", data->target);
        !           691:        if (off < len && data->arg != NULL)
        !           692:                off += cmd_prarg(buf + off, len - off, " ", data->arg);
        !           693:        return (off);
        !           694: }