Annotation of src/usr.bin/tmux/arg.c, Revision 1.2
1.2 ! ray 1: /* $OpenBSD: arg.c,v 1.1 2009/06/01 22:58:49 nicm Exp $ */
1.1 nicm 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);
1.2 ! ray 79: if (n && arg2[n - 1] == ':')
1.1 nicm 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);
1.2 ! ray 104: if (n && arg2[n - 1] == ':')
1.1 nicm 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: }