Annotation of src/usr.bin/tmux/arg.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 <fnmatch.h>
! 22: #include <stdlib.h>
! 23: #include <string.h>
! 24:
! 25: #include "tmux.h"
! 26:
! 27: struct client *arg_lookup_client(const char *);
! 28: struct session *arg_lookup_session(const char *);
! 29:
! 30: struct client *
! 31: arg_lookup_client(const char *name)
! 32: {
! 33: struct client *c;
! 34: u_int i;
! 35:
! 36: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
! 37: c = ARRAY_ITEM(&clients, i);
! 38: if (c != NULL && strcmp(name, c->tty.path) == 0)
! 39: return (c);
! 40: }
! 41:
! 42: return (NULL);
! 43: }
! 44:
! 45: struct session *
! 46: arg_lookup_session(const char *name)
! 47: {
! 48: struct session *s, *newest = NULL;
! 49: struct timeval *tv;
! 50: u_int i;
! 51:
! 52: tv = NULL;
! 53: for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
! 54: s = ARRAY_ITEM(&sessions, i);
! 55: if (s == NULL || fnmatch(name, s->name, 0) != 0)
! 56: continue;
! 57:
! 58: if (tv == NULL || timercmp(&s->tv, tv, >)) {
! 59: newest = s;
! 60: tv = &s->tv;
! 61: }
! 62: }
! 63:
! 64: return (newest);
! 65: }
! 66:
! 67: struct client *
! 68: arg_parse_client(const char *arg)
! 69: {
! 70: struct client *c;
! 71: char *arg2;
! 72: size_t n;
! 73:
! 74: if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) {
! 75: arg2 = xstrdup(arg);
! 76:
! 77: /* Trim a trailing : if any from the argument. */
! 78: n = strlen(arg2);
! 79: if (arg2[n - 1] == ':')
! 80: arg2[n - 1] = '\0';
! 81:
! 82: /* Try and look up the client name. */
! 83: c = arg_lookup_client(arg2);
! 84: xfree(arg2);
! 85: return (c);
! 86: }
! 87:
! 88: return (NULL);
! 89: }
! 90:
! 91: struct session *
! 92: arg_parse_session(const char *arg)
! 93: {
! 94: struct session *s;
! 95: struct client *c;
! 96: char *arg2;
! 97: size_t n;
! 98:
! 99: if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) {
! 100: arg2 = xstrdup(arg);
! 101:
! 102: /* Trim a trailing : if any from the argument. */
! 103: n = strlen(arg2);
! 104: if (arg2[n - 1] == ':')
! 105: arg2[n - 1] = '\0';
! 106:
! 107: /* See if the argument matches a session. */
! 108: if ((s = arg_lookup_session(arg2)) != NULL) {
! 109: xfree(arg2);
! 110: return (s);
! 111: }
! 112:
! 113: /* If not try a client. */
! 114: if ((c = arg_lookup_client(arg2)) != NULL) {
! 115: xfree(arg2);
! 116: return (c->session);
! 117: }
! 118:
! 119: xfree(arg2);
! 120: }
! 121:
! 122: return (NULL);
! 123: }
! 124:
! 125: int
! 126: arg_parse_window(const char *arg, struct session **s, int *idx)
! 127: {
! 128: char *arg2, *ptr;
! 129: const char *errstr;
! 130:
! 131: *idx = -1;
! 132:
! 133: /* Handle no argument or a single :. */
! 134: if (arg == NULL || (arg[0] == ':' && arg[1] == '\0')) {
! 135: *s = arg_parse_session(NULL);
! 136: return (0);
! 137: }
! 138:
! 139: /* Find the separator if any. */
! 140: arg2 = xstrdup(arg);
! 141: ptr = strrchr(arg2, ':');
! 142:
! 143: /*
! 144: * If it is first, this means no session name, so use current session
! 145: * and try to convert the rest as index.
! 146: */
! 147: if (ptr == arg2) {
! 148: *idx = strtonum(ptr + 1, 0, INT_MAX, &errstr);
! 149: if (errstr != NULL) {
! 150: xfree(arg2);
! 151: return (1);
! 152: }
! 153:
! 154: xfree(arg2);
! 155: *s = arg_parse_session(NULL);
! 156: return (0);
! 157: }
! 158:
! 159: /* If missing, try as an index, else look up immediately. */
! 160: if (ptr == NULL) {
! 161: *idx = strtonum(arg2, 0, INT_MAX, &errstr);
! 162: if (errstr == NULL) {
! 163: /* This is good as an index; use current session. */
! 164: xfree(arg2);
! 165: *s = arg_parse_session(NULL);
! 166: return (0);
! 167: }
! 168:
! 169: *idx = -1;
! 170: goto lookup;
! 171: }
! 172:
! 173: /* If last, strip it and look up as a session. */
! 174: if (ptr[1] == '\0') {
! 175: *ptr = '\0';
! 176: goto lookup;
! 177: }
! 178:
! 179: /* Present but not first and not last. Break and convert both. */
! 180: *ptr = '\0';
! 181: *idx = strtonum(ptr + 1, 0, INT_MAX, &errstr);
! 182: if (errstr != NULL) {
! 183: xfree(arg2);
! 184: return (1);
! 185: }
! 186:
! 187: lookup:
! 188: /* Look up as session. */
! 189: *s = arg_parse_session(arg2);
! 190: xfree(arg2);
! 191: if (*s == NULL)
! 192: return (1);
! 193: return (0);
! 194: }