version 1.7, 2009/07/17 18:45:08 |
version 1.8, 2009/07/22 21:23:29 |
|
|
struct client *cmd_lookup_client(const char *); |
struct client *cmd_lookup_client(const char *); |
struct session *cmd_lookup_session(const char *, int *); |
struct session *cmd_lookup_session(const char *, int *); |
struct winlink *cmd_lookup_window(struct session *, const char *, int *); |
struct winlink *cmd_lookup_window(struct session *, const char *, int *); |
|
int cmd_lookup_index(struct session *, const char *, int *); |
|
|
struct cmd * |
struct cmd * |
cmd_parse(int argc, char **argv, char **cause) |
cmd_parse(int argc, char **argv, char **cause) |
|
|
} |
} |
|
|
/* |
/* |
* Lookup a window or return -1 if not found or ambigious. First try as an index |
* Lookup a window or return -1 if not found or ambigious. First try as an |
* and if invalid, use fnmatch or leading prefix. |
* index and if invalid, use fnmatch or leading prefix. Return NULL but fill in |
|
* idx if the window index is a valid number but there is now window with that |
|
* index. |
*/ |
*/ |
struct winlink * |
struct winlink * |
cmd_lookup_window(struct session *s, const char *name, int *ambiguous) |
cmd_lookup_window(struct session *s, const char *name, int *ambiguous) |
{ |
{ |
struct winlink *wl, *wlfound; |
struct winlink *wl, *wlfound; |
struct window *w; |
|
const char *errstr; |
const char *errstr; |
u_int idx; |
u_int idx; |
|
|
|
|
/* Look for exact matches, error if more than one. */ |
/* Look for exact matches, error if more than one. */ |
wlfound = NULL; |
wlfound = NULL; |
RB_FOREACH(wl, winlinks, &s->windows) { |
RB_FOREACH(wl, winlinks, &s->windows) { |
w = wl->window; |
if (strcmp(name, wl->window->name) == 0) { |
if (strcmp(name, w->name) == 0) { |
|
if (wlfound != NULL) { |
if (wlfound != NULL) { |
*ambiguous = 1; |
*ambiguous = 1; |
return (NULL); |
return (NULL); |
|
|
/* Now look for pattern matches, again error if multiple. */ |
/* Now look for pattern matches, again error if multiple. */ |
wlfound = NULL; |
wlfound = NULL; |
RB_FOREACH(wl, winlinks, &s->windows) { |
RB_FOREACH(wl, winlinks, &s->windows) { |
w = wl->window; |
if (strncmp(name, wl->window->name, strlen(name)) == 0 || |
if (strncmp(name, w->name, strlen(name)) == 0 || |
fnmatch(name, wl->window->name, 0) == 0) { |
fnmatch(name, w->name, 0) == 0) { |
|
if (wlfound != NULL) { |
if (wlfound != NULL) { |
*ambiguous = 1; |
*ambiguous = 1; |
return (NULL); |
return (NULL); |
|
|
return (NULL); |
return (NULL); |
} |
} |
|
|
|
/* |
|
* Find a window index - if the window doesn't exist, check if it is a |
|
* potential index and return it anyway. |
|
*/ |
|
int |
|
cmd_lookup_index(struct session *s, const char *name, int *ambiguous) |
|
{ |
|
struct winlink *wl; |
|
const char *errstr; |
|
u_int idx; |
|
|
|
if ((wl = cmd_lookup_window(s, name, ambiguous)) != NULL) |
|
return (wl->idx); |
|
if (*ambiguous) |
|
return (-1); |
|
|
|
idx = strtonum(name, 0, INT_MAX, &errstr); |
|
if (errstr == NULL) |
|
return (idx); |
|
|
|
return (-1); |
|
} |
|
|
/* Find the target session or report an error and return NULL. */ |
/* Find the target session or report an error and return NULL. */ |
struct session * |
struct session * |
cmd_find_session(struct cmd_ctx *ctx, const char *arg) |
cmd_find_session(struct cmd_ctx *ctx, const char *arg) |
|
|
if (*arg == '\0') |
if (*arg == '\0') |
goto not_found; |
goto not_found; |
|
|
/* Find the separating colon. If none, assume the current session. */ |
/* Find the separating colon and split into window and session. */ |
winptr = strchr(arg, ':'); |
winptr = strchr(arg, ':'); |
if (winptr == NULL) |
if (winptr == NULL) |
winptr = xstrdup(arg); |
goto no_colon; |
else { |
winptr++; /* skip : */ |
winptr++; /* skip : */ |
sessptr = xstrdup(arg); |
sessptr = xstrdup(arg); |
*strchr(sessptr, ':') = '\0'; |
*strchr(sessptr, ':') = '\0'; |
|
} |
|
|
|
log_debug("%s: winptr=%s, sessptr=%s", __func__, winptr, sessptr); |
|
|
|
/* Try to lookup the session if present. */ |
/* Try to lookup the session if present. */ |
if (sessptr != NULL && *sessptr != '\0') { |
if (*sessptr != '\0') { |
if ((s = cmd_lookup_session(sessptr, &ambiguous)) == NULL) |
if ((s = cmd_lookup_session(sessptr, &ambiguous)) == NULL) |
goto no_session; |
goto no_session; |
} |
} |
if (sp != NULL) |
if (sp != NULL) |
|
|
* Then work out the window. An empty string is the current window, |
* Then work out the window. An empty string is the current window, |
* otherwise try to look it up in the session. |
* otherwise try to look it up in the session. |
*/ |
*/ |
if (winptr == NULL || *winptr == '\0') |
if (*winptr == '\0') |
wl = s->curw; |
wl = s->curw; |
else if ((wl = cmd_lookup_window(s, winptr, &ambiguous)) == NULL) |
else if ((wl = cmd_lookup_window(s, winptr, &ambiguous)) == NULL) |
goto not_found; |
goto not_found; |
|
|
xfree(sessptr); |
xfree(sessptr); |
return (wl); |
return (wl); |
|
|
|
no_colon: |
|
/* No colon in the string, first try as a window then as a session. */ |
|
if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL) { |
|
if (ambiguous) |
|
goto not_found; |
|
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL) |
|
goto no_session; |
|
wl = s->curw; |
|
} |
|
|
|
if (sp != NULL) |
|
*sp = s; |
|
|
|
return (wl); |
|
|
no_session: |
no_session: |
if (ambiguous) |
if (ambiguous) |
ctx->error(ctx, "multiple sessions: %s", sessptr); |
ctx->error(ctx, "multiple sessions: %s", arg); |
else |
else |
ctx->error(ctx, "session not found: %s", sessptr); |
ctx->error(ctx, "session not found: %s", arg); |
if (sessptr != NULL) |
if (sessptr != NULL) |
xfree(sessptr); |
xfree(sessptr); |
return (NULL); |
return (NULL); |
|
|
/* |
/* |
* Find the target session and window index, whether or not it exists in the |
* Find the target session and window index, whether or not it exists in the |
* session. Return -2 on error or -1 if no window index is specified. This is |
* session. Return -2 on error or -1 if no window index is specified. This is |
* used when parsing an argument for a window target that may not be exist (for |
* used when parsing an argument for a window target that may not exist (for |
* example it is going to be created). |
* example if it is going to be created). |
*/ |
*/ |
int |
int |
cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp) |
cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp) |
{ |
{ |
struct session *s; |
struct session *s; |
struct winlink *wl; |
const char *winptr; |
const char *winptr, *errstr; |
|
char *sessptr = NULL; |
char *sessptr = NULL; |
int idx, ambiguous = 0; |
int idx, ambiguous = 0; |
|
|
|
|
/* Find the separating colon. If none, assume the current session. */ |
/* Find the separating colon. If none, assume the current session. */ |
winptr = strchr(arg, ':'); |
winptr = strchr(arg, ':'); |
if (winptr == NULL) |
if (winptr == NULL) |
winptr = xstrdup(arg); |
goto no_colon; |
else { |
winptr++; /* skip : */ |
winptr++; /* skip : */ |
sessptr = xstrdup(arg); |
sessptr = xstrdup(arg); |
*strchr(sessptr, ':') = '\0'; |
*strchr(sessptr, ':') = '\0'; |
|
} |
|
|
|
log_debug("%s: winptr=%s, sessptr=%s", __func__, winptr, sessptr); |
|
|
|
/* Try to lookup the session if present. */ |
/* Try to lookup the session if present. */ |
if (sessptr != NULL && *sessptr != '\0') { |
if (sessptr != NULL && *sessptr != '\0') { |
if ((s = cmd_lookup_session(sessptr, &ambiguous)) == NULL) |
if ((s = cmd_lookup_session(sessptr, &ambiguous)) == NULL) |
goto no_session; |
goto no_session; |
} |
} |
if (sp != NULL) |
if (sp != NULL) |
*sp = s; |
*sp = s; |
|
|
/* |
/* |
* Then work out the window. No : means "no window" (-1), an empty |
* Then work out the window. An empty string is a new window otherwise |
* string is the current window, otherwise try to look it up in the |
* try to look it up in the session. |
* session. |
|
*/ |
*/ |
if (winptr == NULL) |
if (*winptr == '\0') |
idx = -1; |
idx = -1; |
else if (*winptr == '\0') |
else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1) { |
idx = s->curw->idx; |
|
else if ((wl = cmd_lookup_window(s, winptr, &ambiguous)) == NULL) { |
|
if (ambiguous) |
if (ambiguous) |
goto not_found; |
goto not_found; |
/* Don't care it doesn't exist if this is a valid index. */ |
ctx->error(ctx, "invalid index: %s", arg); |
idx = strtonum(winptr, 0, INT_MAX, &errstr); |
idx = -2; |
if (errstr != NULL) { |
} |
ctx->error(ctx, "index %s: %s", errstr, winptr); |
|
idx = -2; |
|
} |
|
} else |
|
idx = wl->idx; |
|
|
|
if (sessptr != NULL) |
if (sessptr != NULL) |
xfree(sessptr); |
xfree(sessptr); |
return (idx); |
return (idx); |
|
|
|
no_colon: |
|
/* No colon in the string, first try as a window then as a session. */ |
|
if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1) { |
|
if (ambiguous) |
|
goto not_found; |
|
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL) |
|
goto no_session; |
|
idx = -1; |
|
} |
|
|
|
if (sp != NULL) |
|
*sp = s; |
|
|
|
return (idx); |
|
|
no_session: |
no_session: |
if (ambiguous) |
if (ambiguous) |
ctx->error(ctx, "multiple sessions: %s", sessptr); |
ctx->error(ctx, "multiple sessions: %s", arg); |
else |
else |
ctx->error(ctx, "session not found: %s", sessptr); |
ctx->error(ctx, "session not found: %s", arg); |
if (sessptr != NULL) |
if (sessptr != NULL) |
xfree(sessptr); |
xfree(sessptr); |
return (-2); |
return (-2); |