xref: /openbsd-src/usr.bin/tmux/format.c (revision be691f3bb6417f04a68938fadbcaee2d5795e764)
1 /* $OpenBSD: format.c,v 1.299 2021/10/25 21:21:16 nicm Exp $ */
2 
3 /*
4  * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
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 #include <sys/wait.h>
21 
22 #include <ctype.h>
23 #include <errno.h>
24 #include <fnmatch.h>
25 #include <libgen.h>
26 #include <math.h>
27 #include <regex.h>
28 #include <stdarg.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <time.h>
32 #include <unistd.h>
33 
34 #include "tmux.h"
35 
36 /*
37  * Build a list of key-value pairs and use them to expand #{key} entries in a
38  * string.
39  */
40 
41 struct format_expand_state;
42 
43 static char	*format_job_get(struct format_expand_state *, const char *);
44 static char	*format_expand1(struct format_expand_state *, const char *);
45 static int	 format_replace(struct format_expand_state *, const char *,
46 		     size_t, char **, size_t *, size_t *);
47 static void	 format_defaults_session(struct format_tree *,
48 		     struct session *);
49 static void	 format_defaults_client(struct format_tree *, struct client *);
50 static void	 format_defaults_winlink(struct format_tree *,
51 		     struct winlink *);
52 
53 /* Entry in format job tree. */
54 struct format_job {
55 	struct client		*client;
56 	u_int			 tag;
57 	const char		*cmd;
58 	const char		*expanded;
59 
60 	time_t			 last;
61 	char			*out;
62 	int			 updated;
63 
64 	struct job		*job;
65 	int			 status;
66 
67 	RB_ENTRY(format_job)	 entry;
68 };
69 
70 /* Format job tree. */
71 static int format_job_cmp(struct format_job *, struct format_job *);
72 static RB_HEAD(format_job_tree, format_job) format_jobs = RB_INITIALIZER();
73 RB_GENERATE_STATIC(format_job_tree, format_job, entry, format_job_cmp);
74 
75 /* Format job tree comparison function. */
76 static int
77 format_job_cmp(struct format_job *fj1, struct format_job *fj2)
78 {
79 	if (fj1->tag < fj2->tag)
80 		return (-1);
81 	if (fj1->tag > fj2->tag)
82 		return (1);
83 	return (strcmp(fj1->cmd, fj2->cmd));
84 }
85 
86 /* Format modifiers. */
87 #define FORMAT_TIMESTRING 0x1
88 #define FORMAT_BASENAME 0x2
89 #define FORMAT_DIRNAME 0x4
90 #define FORMAT_QUOTE_SHELL 0x8
91 #define FORMAT_LITERAL 0x10
92 #define FORMAT_EXPAND 0x20
93 #define FORMAT_EXPANDTIME 0x40
94 #define FORMAT_SESSIONS 0x80
95 #define FORMAT_WINDOWS 0x100
96 #define FORMAT_PANES 0x200
97 #define FORMAT_PRETTY 0x400
98 #define FORMAT_LENGTH 0x800
99 #define FORMAT_WIDTH 0x1000
100 #define FORMAT_QUOTE_STYLE 0x2000
101 #define FORMAT_WINDOW_NAME 0x4000
102 #define FORMAT_SESSION_NAME 0x8000
103 #define FORMAT_CHARACTER 0x10000
104 #define FORMAT_COLOUR 0x20000
105 
106 /* Limit on recursion. */
107 #define FORMAT_LOOP_LIMIT 100
108 
109 /* Format expand flags. */
110 #define FORMAT_EXPAND_TIME 0x1
111 #define FORMAT_EXPAND_NOJOBS 0x2
112 
113 /* Entry in format tree. */
114 struct format_entry {
115 	char			*key;
116 	char			*value;
117 	time_t			 time;
118 	format_cb		 cb;
119 	RB_ENTRY(format_entry)	 entry;
120 };
121 
122 /* Format type. */
123 enum format_type {
124 	FORMAT_TYPE_UNKNOWN,
125 	FORMAT_TYPE_SESSION,
126 	FORMAT_TYPE_WINDOW,
127 	FORMAT_TYPE_PANE
128 };
129 
130 struct format_tree {
131 	enum format_type	 type;
132 
133 	struct client		*c;
134 	struct session		*s;
135 	struct winlink		*wl;
136 	struct window		*w;
137 	struct window_pane	*wp;
138 	struct paste_buffer	*pb;
139 
140 	struct cmdq_item	*item;
141 	struct client		*client;
142 	int			 flags;
143 	u_int			 tag;
144 
145 	struct mouse_event	 m;
146 
147 	RB_HEAD(format_entry_tree, format_entry) tree;
148 };
149 static int format_entry_cmp(struct format_entry *, struct format_entry *);
150 RB_GENERATE_STATIC(format_entry_tree, format_entry, entry, format_entry_cmp);
151 
152 /* Format expand state. */
153 struct format_expand_state {
154 	struct format_tree	*ft;
155 	u_int			 loop;
156 	time_t			 time;
157 	struct tm		 tm;
158 	int			 flags;
159 };
160 
161 /* Format modifier. */
162 struct format_modifier {
163 	char	  modifier[3];
164 	u_int	  size;
165 
166 	char	**argv;
167 	int	  argc;
168 };
169 
170 /* Format entry tree comparison function. */
171 static int
172 format_entry_cmp(struct format_entry *fe1, struct format_entry *fe2)
173 {
174 	return (strcmp(fe1->key, fe2->key));
175 }
176 
177 /* Single-character uppercase aliases. */
178 static const char *format_upper[] = {
179 	NULL,		/* A */
180 	NULL,		/* B */
181 	NULL,		/* C */
182 	"pane_id",	/* D */
183 	NULL,		/* E */
184 	"window_flags",	/* F */
185 	NULL,		/* G */
186 	"host",		/* H */
187 	"window_index",	/* I */
188 	NULL,		/* J */
189 	NULL,		/* K */
190 	NULL,		/* L */
191 	NULL,		/* M */
192 	NULL,		/* N */
193 	NULL,		/* O */
194 	"pane_index",	/* P */
195 	NULL,		/* Q */
196 	NULL,		/* R */
197 	"session_name",	/* S */
198 	"pane_title",	/* T */
199 	NULL,		/* U */
200 	NULL,		/* V */
201 	"window_name",	/* W */
202 	NULL,		/* X */
203 	NULL,		/* Y */
204 	NULL 		/* Z */
205 };
206 
207 /* Single-character lowercase aliases. */
208 static const char *format_lower[] = {
209 	NULL,		/* a */
210 	NULL,		/* b */
211 	NULL,		/* c */
212 	NULL,		/* d */
213 	NULL,		/* e */
214 	NULL,		/* f */
215 	NULL,		/* g */
216 	"host_short",	/* h */
217 	NULL,		/* i */
218 	NULL,		/* j */
219 	NULL,		/* k */
220 	NULL,		/* l */
221 	NULL,		/* m */
222 	NULL,		/* n */
223 	NULL,		/* o */
224 	NULL,		/* p */
225 	NULL,		/* q */
226 	NULL,		/* r */
227 	NULL,		/* s */
228 	NULL,		/* t */
229 	NULL,		/* u */
230 	NULL,		/* v */
231 	NULL,		/* w */
232 	NULL,		/* x */
233 	NULL,		/* y */
234 	NULL		/* z */
235 };
236 
237 /* Is logging enabled? */
238 static inline int
239 format_logging(struct format_tree *ft)
240 {
241 	return (log_get_level() != 0 || (ft->flags & FORMAT_VERBOSE));
242 }
243 
244 /* Log a message if verbose. */
245 static void printflike(3, 4)
246 format_log1(struct format_expand_state *es, const char *from, const char *fmt,
247     ...)
248 {
249 	struct format_tree	*ft = es->ft;
250 	va_list			 ap;
251 	char			*s;
252 	static const char	 spaces[] = "          ";
253 
254 	if (!format_logging(ft))
255 		return;
256 
257 	va_start(ap, fmt);
258 	xvasprintf(&s, fmt, ap);
259 	va_end(ap);
260 
261 	log_debug("%s: %s", from, s);
262 	if (ft->item != NULL && (ft->flags & FORMAT_VERBOSE))
263 		cmdq_print(ft->item, "#%.*s%s", es->loop, spaces, s);
264 
265 	free(s);
266 }
267 #define format_log(es, fmt, ...) format_log1(es, __func__, fmt, ##__VA_ARGS__)
268 
269 /* Copy expand state. */
270 static void
271 format_copy_state(struct format_expand_state *to,
272     struct format_expand_state *from, int flags)
273 {
274 	to->ft = from->ft;
275 	to->loop = from->loop;
276 	to->time = from->time;
277 	memcpy(&to->tm, &from->tm, sizeof to->tm);
278 	to->flags = from->flags|flags;
279 }
280 
281 /* Format job update callback. */
282 static void
283 format_job_update(struct job *job)
284 {
285 	struct format_job	*fj = job_get_data(job);
286 	struct evbuffer		*evb = job_get_event(job)->input;
287 	char			*line = NULL, *next;
288 	time_t			 t;
289 
290 	while ((next = evbuffer_readline(evb)) != NULL) {
291 		free(line);
292 		line = next;
293 	}
294 	if (line == NULL)
295 		return;
296 	fj->updated = 1;
297 
298 	free(fj->out);
299 	fj->out = line;
300 
301 	log_debug("%s: %p %s: %s", __func__, fj, fj->cmd, fj->out);
302 
303 	t = time(NULL);
304 	if (fj->status && fj->last != t) {
305 		if (fj->client != NULL)
306 			server_status_client(fj->client);
307 		fj->last = t;
308 	}
309 }
310 
311 /* Format job complete callback. */
312 static void
313 format_job_complete(struct job *job)
314 {
315 	struct format_job	*fj = job_get_data(job);
316 	struct evbuffer		*evb = job_get_event(job)->input;
317 	char			*line, *buf;
318 	size_t			 len;
319 
320 	fj->job = NULL;
321 
322 	buf = NULL;
323 	if ((line = evbuffer_readline(evb)) == NULL) {
324 		len = EVBUFFER_LENGTH(evb);
325 		buf = xmalloc(len + 1);
326 		if (len != 0)
327 			memcpy(buf, EVBUFFER_DATA(evb), len);
328 		buf[len] = '\0';
329 	} else
330 		buf = line;
331 
332 	log_debug("%s: %p %s: %s", __func__, fj, fj->cmd, buf);
333 
334 	if (*buf != '\0' || !fj->updated) {
335 		free(fj->out);
336 		fj->out = buf;
337 	} else
338 		free(buf);
339 
340 	if (fj->status) {
341 		if (fj->client != NULL)
342 			server_status_client(fj->client);
343 		fj->status = 0;
344 	}
345 }
346 
347 /* Find a job. */
348 static char *
349 format_job_get(struct format_expand_state *es, const char *cmd)
350 {
351 	struct format_tree		*ft = es->ft;
352 	struct format_job_tree		*jobs;
353 	struct format_job		 fj0, *fj;
354 	time_t				 t;
355 	char				*expanded;
356 	int				 force;
357 	struct format_expand_state	 next;
358 
359 	if (ft->client == NULL)
360 		jobs = &format_jobs;
361 	else if (ft->client->jobs != NULL)
362 		jobs = ft->client->jobs;
363 	else {
364 		jobs = ft->client->jobs = xmalloc(sizeof *ft->client->jobs);
365 		RB_INIT(jobs);
366 	}
367 
368 	fj0.tag = ft->tag;
369 	fj0.cmd = cmd;
370 	if ((fj = RB_FIND(format_job_tree, jobs, &fj0)) == NULL) {
371 		fj = xcalloc(1, sizeof *fj);
372 		fj->client = ft->client;
373 		fj->tag = ft->tag;
374 		fj->cmd = xstrdup(cmd);
375 
376 		RB_INSERT(format_job_tree, jobs, fj);
377 	}
378 
379 	format_copy_state(&next, es, FORMAT_EXPAND_NOJOBS);
380 	next.flags &= ~FORMAT_EXPAND_TIME;
381 
382 	expanded = format_expand1(&next, cmd);
383 	if (fj->expanded == NULL || strcmp(expanded, fj->expanded) != 0) {
384 		free((void *)fj->expanded);
385 		fj->expanded = xstrdup(expanded);
386 		force = 1;
387 	} else
388 		force = (ft->flags & FORMAT_FORCE);
389 
390 	t = time(NULL);
391 	if (force && fj->job != NULL)
392 	       job_free(fj->job);
393 	if (force || (fj->job == NULL && fj->last != t)) {
394 		fj->job = job_run(expanded, 0, NULL, NULL, NULL,
395 		    server_client_get_cwd(ft->client, NULL), format_job_update,
396 		    format_job_complete, NULL, fj, JOB_NOWAIT, -1, -1);
397 		if (fj->job == NULL) {
398 			free(fj->out);
399 			xasprintf(&fj->out, "<'%s' didn't start>", fj->cmd);
400 		}
401 		fj->last = t;
402 		fj->updated = 0;
403 	} else if (fj->job != NULL && (t - fj->last) > 1 && fj->out == NULL)
404 		xasprintf(&fj->out, "<'%s' not ready>", fj->cmd);
405 	free(expanded);
406 
407 	if (ft->flags & FORMAT_STATUS)
408 		fj->status = 1;
409 	if (fj->out == NULL)
410 		return (xstrdup(""));
411 	return (format_expand1(&next, fj->out));
412 }
413 
414 /* Remove old jobs. */
415 static void
416 format_job_tidy(struct format_job_tree *jobs, int force)
417 {
418 	struct format_job	*fj, *fj1;
419 	time_t			 now;
420 
421 	now = time(NULL);
422 	RB_FOREACH_SAFE(fj, format_job_tree, jobs, fj1) {
423 		if (!force && (fj->last > now || now - fj->last < 3600))
424 			continue;
425 		RB_REMOVE(format_job_tree, jobs, fj);
426 
427 		log_debug("%s: %s", __func__, fj->cmd);
428 
429 		if (fj->job != NULL)
430 			job_free(fj->job);
431 
432 		free((void *)fj->expanded);
433 		free((void *)fj->cmd);
434 		free(fj->out);
435 
436 		free(fj);
437 	}
438 }
439 
440 /* Tidy old jobs for all clients. */
441 void
442 format_tidy_jobs(void)
443 {
444 	struct client	*c;
445 
446 	format_job_tidy(&format_jobs, 0);
447 	TAILQ_FOREACH(c, &clients, entry) {
448 		if (c->jobs != NULL)
449 			format_job_tidy(c->jobs, 0);
450 	}
451 }
452 
453 /* Remove old jobs for client. */
454 void
455 format_lost_client(struct client *c)
456 {
457 	if (c->jobs != NULL)
458 		format_job_tidy(c->jobs, 1);
459 	free(c->jobs);
460 }
461 
462 /* Wrapper for asprintf. */
463 static char * printflike(1, 2)
464 format_printf(const char *fmt, ...)
465 {
466 	va_list	 ap;
467 	char	*s;
468 
469 	va_start(ap, fmt);
470 	xvasprintf(&s, fmt, ap);
471 	va_end(ap);
472 	return (s);
473 }
474 
475 /* Callback for host. */
476 static void *
477 format_cb_host(__unused struct format_tree *ft)
478 {
479 	char host[HOST_NAME_MAX + 1];
480 
481 	if (gethostname(host, sizeof host) != 0)
482 		return (xstrdup(""));
483 	return (xstrdup(host));
484 }
485 
486 /* Callback for host_short. */
487 static void *
488 format_cb_host_short(__unused struct format_tree *ft)
489 {
490 	char host[HOST_NAME_MAX + 1], *cp;
491 
492 	if (gethostname(host, sizeof host) != 0)
493 		return (xstrdup(""));
494 	if ((cp = strchr(host, '.')) != NULL)
495 		*cp = '\0';
496 	return (xstrdup(host));
497 }
498 
499 /* Callback for pid. */
500 static void *
501 format_cb_pid(__unused struct format_tree *ft)
502 {
503 	char	*value;
504 
505 	xasprintf(&value, "%ld", (long)getpid());
506 	return (value);
507 }
508 
509 /* Callback for session_attached_list. */
510 static void *
511 format_cb_session_attached_list(struct format_tree *ft)
512 {
513 	struct session	*s = ft->s;
514 	struct client	*loop;
515 	struct evbuffer	*buffer;
516 	int		 size;
517 	char		*value = NULL;
518 
519 	if (s == NULL)
520 		return (NULL);
521 
522 	buffer = evbuffer_new();
523 	if (buffer == NULL)
524 		fatalx("out of memory");
525 
526 	TAILQ_FOREACH(loop, &clients, entry) {
527 		if (loop->session == s) {
528 			if (EVBUFFER_LENGTH(buffer) > 0)
529 				evbuffer_add(buffer, ",", 1);
530 			evbuffer_add_printf(buffer, "%s", loop->name);
531 		}
532 	}
533 
534 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
535 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
536 	evbuffer_free(buffer);
537 	return (value);
538 }
539 
540 /* Callback for session_alerts. */
541 static void *
542 format_cb_session_alerts(struct format_tree *ft)
543 {
544 	struct session	*s = ft->s;
545 	struct winlink	*wl;
546 	char		 alerts[1024], tmp[16];
547 
548 	if (s == NULL)
549 		return (NULL);
550 
551 	*alerts = '\0';
552 	RB_FOREACH(wl, winlinks, &s->windows) {
553 		if ((wl->flags & WINLINK_ALERTFLAGS) == 0)
554 			continue;
555 		xsnprintf(tmp, sizeof tmp, "%u", wl->idx);
556 
557 		if (*alerts != '\0')
558 			strlcat(alerts, ",", sizeof alerts);
559 		strlcat(alerts, tmp, sizeof alerts);
560 		if (wl->flags & WINLINK_ACTIVITY)
561 			strlcat(alerts, "#", sizeof alerts);
562 		if (wl->flags & WINLINK_BELL)
563 			strlcat(alerts, "!", sizeof alerts);
564 		if (wl->flags & WINLINK_SILENCE)
565 			strlcat(alerts, "~", sizeof alerts);
566 	}
567 	return (xstrdup(alerts));
568 }
569 
570 /* Callback for session_stack. */
571 static void *
572 format_cb_session_stack(struct format_tree *ft)
573 {
574 	struct session	*s = ft->s;
575 	struct winlink	*wl;
576 	char		 result[1024], tmp[16];
577 
578 	if (s == NULL)
579 		return (NULL);
580 
581 	xsnprintf(result, sizeof result, "%u", s->curw->idx);
582 	TAILQ_FOREACH(wl, &s->lastw, sentry) {
583 		xsnprintf(tmp, sizeof tmp, "%u", wl->idx);
584 
585 		if (*result != '\0')
586 			strlcat(result, ",", sizeof result);
587 		strlcat(result, tmp, sizeof result);
588 	}
589 	return (xstrdup(result));
590 }
591 
592 /* Callback for window_stack_index. */
593 static void *
594 format_cb_window_stack_index(struct format_tree *ft)
595 {
596 	struct session	*s;
597 	struct winlink	*wl;
598 	u_int		 idx;
599 	char		*value = NULL;
600 
601 	if (ft->wl == NULL)
602 		return (NULL);
603 	s = ft->wl->session;
604 
605 	idx = 0;
606 	TAILQ_FOREACH(wl, &s->lastw, sentry) {
607 		idx++;
608 		if (wl == ft->wl)
609 			break;
610 	}
611 	if (wl == NULL)
612 		return (xstrdup("0"));
613 	xasprintf(&value, "%u", idx);
614 	return (value);
615 }
616 
617 /* Callback for window_linked_sessions_list. */
618 static void *
619 format_cb_window_linked_sessions_list(struct format_tree *ft)
620 {
621 	struct window	*w;
622 	struct winlink	*wl;
623 	struct evbuffer	*buffer;
624 	int		 size;
625 	char		*value = NULL;
626 
627 	if (ft->wl == NULL)
628 		return (NULL);
629 	w = ft->wl->window;
630 
631 	buffer = evbuffer_new();
632 	if (buffer == NULL)
633 		fatalx("out of memory");
634 
635 	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
636 		if (EVBUFFER_LENGTH(buffer) > 0)
637 			evbuffer_add(buffer, ",", 1);
638 		evbuffer_add_printf(buffer, "%s", wl->session->name);
639 	}
640 
641 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
642 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
643 	evbuffer_free(buffer);
644 	return (value);
645 }
646 
647 /* Callback for window_active_sessions. */
648 static void *
649 format_cb_window_active_sessions(struct format_tree *ft)
650 {
651 	struct window	*w;
652 	struct winlink	*wl;
653 	u_int		 n = 0;
654 	char		*value;
655 
656 	if (ft->wl == NULL)
657 		return (NULL);
658 	w = ft->wl->window;
659 
660 	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
661 		if (wl->session->curw == wl)
662 			n++;
663 	}
664 
665 	xasprintf(&value, "%u", n);
666 	return (value);
667 }
668 
669 /* Callback for window_active_sessions_list. */
670 static void *
671 format_cb_window_active_sessions_list(struct format_tree *ft)
672 {
673 	struct window	*w;
674 	struct winlink	*wl;
675 	struct evbuffer	*buffer;
676 	int		 size;
677 	char		*value = NULL;
678 
679 	if (ft->wl == NULL)
680 		return (NULL);
681 	w = ft->wl->window;
682 
683 	buffer = evbuffer_new();
684 	if (buffer == NULL)
685 		fatalx("out of memory");
686 
687 	TAILQ_FOREACH(wl, &w->winlinks, wentry) {
688 		if (wl->session->curw == wl) {
689 			if (EVBUFFER_LENGTH(buffer) > 0)
690 				evbuffer_add(buffer, ",", 1);
691 			evbuffer_add_printf(buffer, "%s", wl->session->name);
692 		}
693 	}
694 
695 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
696 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
697 	evbuffer_free(buffer);
698 	return (value);
699 }
700 
701 /* Callback for window_active_clients. */
702 static void *
703 format_cb_window_active_clients(struct format_tree *ft)
704 {
705 	struct window	*w;
706 	struct client	*loop;
707 	struct session	*client_session;
708 	u_int		 n = 0;
709 	char		*value;
710 
711 	if (ft->wl == NULL)
712 		return (NULL);
713 	w = ft->wl->window;
714 
715 	TAILQ_FOREACH(loop, &clients, entry) {
716 		client_session = loop->session;
717 		if (client_session == NULL)
718 			continue;
719 
720 		if (w == client_session->curw->window)
721 			n++;
722 	}
723 
724 	xasprintf(&value, "%u", n);
725 	return (value);
726 }
727 
728 /* Callback for window_active_clients_list. */
729 static void *
730 format_cb_window_active_clients_list(struct format_tree *ft)
731 {
732 	struct window	*w;
733 	struct client	*loop;
734 	struct session	*client_session;
735 	struct evbuffer	*buffer;
736 	int		 size;
737 	char		*value = NULL;
738 
739 	if (ft->wl == NULL)
740 		return (NULL);
741 	w = ft->wl->window;
742 
743 	buffer = evbuffer_new();
744 	if (buffer == NULL)
745 		fatalx("out of memory");
746 
747 	TAILQ_FOREACH(loop, &clients, entry) {
748 		client_session = loop->session;
749 		if (client_session == NULL)
750 			continue;
751 
752 		if (w == client_session->curw->window) {
753 			if (EVBUFFER_LENGTH(buffer) > 0)
754 				evbuffer_add(buffer, ",", 1);
755 			evbuffer_add_printf(buffer, "%s", loop->name);
756 		}
757 	}
758 
759 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
760 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
761 	evbuffer_free(buffer);
762 	return (value);
763 }
764 
765 /* Callback for window_layout. */
766 static void *
767 format_cb_window_layout(struct format_tree *ft)
768 {
769 	struct window	*w = ft->w;
770 
771 	if (w == NULL)
772 		return (NULL);
773 
774 	if (w->saved_layout_root != NULL)
775 		return (layout_dump(w->saved_layout_root));
776 	return (layout_dump(w->layout_root));
777 }
778 
779 /* Callback for window_visible_layout. */
780 static void *
781 format_cb_window_visible_layout(struct format_tree *ft)
782 {
783 	struct window	*w = ft->w;
784 
785 	if (w == NULL)
786 		return (NULL);
787 
788 	return (layout_dump(w->layout_root));
789 }
790 
791 /* Callback for pane_start_command. */
792 static void *
793 format_cb_start_command(struct format_tree *ft)
794 {
795 	struct window_pane	*wp = ft->wp;
796 
797 	if (wp == NULL)
798 		return (NULL);
799 
800 	return (cmd_stringify_argv(wp->argc, wp->argv));
801 }
802 
803 /* Callback for pane_current_command. */
804 static void *
805 format_cb_current_command(struct format_tree *ft)
806 {
807 	struct window_pane	*wp = ft->wp;
808 	char			*cmd, *value;
809 
810 	if (wp == NULL || wp->shell == NULL)
811 		return (NULL);
812 
813 	cmd = get_proc_name(wp->fd, wp->tty);
814 	if (cmd == NULL || *cmd == '\0') {
815 		free(cmd);
816 		cmd = cmd_stringify_argv(wp->argc, wp->argv);
817 		if (cmd == NULL || *cmd == '\0') {
818 			free(cmd);
819 			cmd = xstrdup(wp->shell);
820 		}
821 	}
822 	value = parse_window_name(cmd);
823 	free(cmd);
824 	return (value);
825 }
826 
827 /* Callback for pane_current_path. */
828 static void *
829 format_cb_current_path(struct format_tree *ft)
830 {
831 	struct window_pane	*wp = ft->wp;
832 	char			*cwd;
833 
834 	if (wp == NULL)
835 		return (NULL);
836 
837 	cwd = get_proc_cwd(wp->fd);
838 	if (cwd == NULL)
839 		return (NULL);
840 	return (xstrdup(cwd));
841 }
842 
843 /* Callback for history_bytes. */
844 static void *
845 format_cb_history_bytes(struct format_tree *ft)
846 {
847 	struct window_pane	*wp = ft->wp;
848 	struct grid		*gd;
849 	struct grid_line	*gl;
850 	size_t		         size = 0;
851 	u_int			 i;
852 	char			*value;
853 
854 	if (wp == NULL)
855 		return (NULL);
856 	gd = wp->base.grid;
857 
858 	for (i = 0; i < gd->hsize + gd->sy; i++) {
859 		gl = grid_get_line(gd, i);
860 		size += gl->cellsize * sizeof *gl->celldata;
861 		size += gl->extdsize * sizeof *gl->extddata;
862 	}
863 	size += (gd->hsize + gd->sy) * sizeof *gl;
864 
865 	xasprintf(&value, "%zu", size);
866 	return (value);
867 }
868 
869 /* Callback for history_all_bytes. */
870 static void *
871 format_cb_history_all_bytes(struct format_tree *ft)
872 {
873 	struct window_pane	*wp = ft->wp;
874 	struct grid		*gd;
875 	struct grid_line	*gl;
876 	u_int			 i, lines, cells = 0, extended_cells = 0;
877 	char			*value;
878 
879 	if (wp == NULL)
880 		return (NULL);
881 	gd = wp->base.grid;
882 
883 	lines = gd->hsize + gd->sy;
884 	for (i = 0; i < lines; i++) {
885 		gl = grid_get_line(gd, i);
886 		cells += gl->cellsize;
887 		extended_cells += gl->extdsize;
888 	}
889 
890 	xasprintf(&value, "%u,%zu,%u,%zu,%u,%zu", lines,
891 	    lines * sizeof *gl, cells, cells * sizeof *gl->celldata,
892 	    extended_cells, extended_cells * sizeof *gl->extddata);
893 	return (value);
894 }
895 
896 /* Callback for pane_tabs. */
897 static void *
898 format_cb_pane_tabs(struct format_tree *ft)
899 {
900 	struct window_pane	*wp = ft->wp;
901 	struct evbuffer		*buffer;
902 	u_int			 i;
903 	int			 size;
904 	char			*value = NULL;
905 
906 	if (wp == NULL)
907 		return (NULL);
908 
909 	buffer = evbuffer_new();
910 	if (buffer == NULL)
911 		fatalx("out of memory");
912 	for (i = 0; i < wp->base.grid->sx; i++) {
913 		if (!bit_test(wp->base.tabs, i))
914 			continue;
915 
916 		if (EVBUFFER_LENGTH(buffer) > 0)
917 			evbuffer_add(buffer, ",", 1);
918 		evbuffer_add_printf(buffer, "%u", i);
919 	}
920 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
921 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
922 	evbuffer_free(buffer);
923 	return (value);
924 }
925 
926 /* Callback for pane_fg. */
927 static void *
928 format_cb_pane_fg(struct format_tree *ft)
929 {
930 	struct window_pane	*wp = ft->wp;
931 	struct grid_cell	 gc;
932 
933 	if (wp == NULL)
934 		return (NULL);
935 
936 	tty_default_colours(&gc, wp);
937 	return (xstrdup(colour_tostring(gc.fg)));
938 }
939 
940 /* Callback for pane_bg. */
941 static void *
942 format_cb_pane_bg(struct format_tree *ft)
943 {
944 	struct window_pane	*wp = ft->wp;
945 	struct grid_cell	 gc;
946 
947 	if (wp == NULL)
948 		return (NULL);
949 
950 	tty_default_colours(&gc, wp);
951 	return (xstrdup(colour_tostring(gc.bg)));
952 }
953 
954 /* Callback for session_group_list. */
955 static void *
956 format_cb_session_group_list(struct format_tree *ft)
957 {
958 	struct session		*s = ft->s;
959 	struct session_group	*sg;
960 	struct session		*loop;
961 	struct evbuffer		*buffer;
962 	int			 size;
963 	char			*value = NULL;
964 
965 	if (s == NULL)
966 		return (NULL);
967 	sg = session_group_contains(s);
968 	if (sg == NULL)
969 		return (NULL);
970 
971 	buffer = evbuffer_new();
972 	if (buffer == NULL)
973 		fatalx("out of memory");
974 
975 	TAILQ_FOREACH(loop, &sg->sessions, gentry) {
976 		if (EVBUFFER_LENGTH(buffer) > 0)
977 			evbuffer_add(buffer, ",", 1);
978 		evbuffer_add_printf(buffer, "%s", loop->name);
979 	}
980 
981 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
982 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
983 	evbuffer_free(buffer);
984 	return (value);
985 }
986 
987 /* Callback for session_group_attached_list. */
988 static void *
989 format_cb_session_group_attached_list(struct format_tree *ft)
990 {
991 	struct session		*s = ft->s, *client_session, *session_loop;
992 	struct session_group	*sg;
993 	struct client		*loop;
994 	struct evbuffer		*buffer;
995 	int			 size;
996 	char			*value = NULL;
997 
998 	if (s == NULL)
999 		return (NULL);
1000 	sg = session_group_contains(s);
1001 	if (sg == NULL)
1002 		return (NULL);
1003 
1004 	buffer = evbuffer_new();
1005 	if (buffer == NULL)
1006 		fatalx("out of memory");
1007 
1008 	TAILQ_FOREACH(loop, &clients, entry) {
1009 		client_session = loop->session;
1010 		if (client_session == NULL)
1011 			continue;
1012 		TAILQ_FOREACH(session_loop, &sg->sessions, gentry) {
1013 			if (session_loop == client_session){
1014 				if (EVBUFFER_LENGTH(buffer) > 0)
1015 					evbuffer_add(buffer, ",", 1);
1016 				evbuffer_add_printf(buffer, "%s", loop->name);
1017 			}
1018 		}
1019 	}
1020 
1021 	if ((size = EVBUFFER_LENGTH(buffer)) != 0)
1022 		xasprintf(&value, "%.*s", size, EVBUFFER_DATA(buffer));
1023 	evbuffer_free(buffer);
1024 	return (value);
1025 }
1026 
1027 /* Callback for pane_in_mode. */
1028 static void *
1029 format_cb_pane_in_mode(struct format_tree *ft)
1030 {
1031 	struct window_pane		*wp = ft->wp;
1032 	u_int				 n = 0;
1033 	struct window_mode_entry	*wme;
1034 	char				*value;
1035 
1036 	if (wp == NULL)
1037 		return (NULL);
1038 
1039 	TAILQ_FOREACH(wme, &wp->modes, entry)
1040 		n++;
1041 	xasprintf(&value, "%u", n);
1042 	return (value);
1043 }
1044 
1045 /* Callback for pane_at_top. */
1046 static void *
1047 format_cb_pane_at_top(struct format_tree *ft)
1048 {
1049 	struct window_pane	*wp = ft->wp;
1050 	struct window		*w;
1051 	int			 status, flag;
1052 	char			*value;
1053 
1054 	if (wp == NULL)
1055 		return (NULL);
1056 	w = wp->window;
1057 
1058 	status = options_get_number(w->options, "pane-border-status");
1059 	if (status == PANE_STATUS_TOP)
1060 		flag = (wp->yoff == 1);
1061 	else
1062 		flag = (wp->yoff == 0);
1063 	xasprintf(&value, "%d", flag);
1064 	return (value);
1065 }
1066 
1067 /* Callback for pane_at_bottom. */
1068 static void *
1069 format_cb_pane_at_bottom(struct format_tree *ft)
1070 {
1071 	struct window_pane	*wp = ft->wp;
1072 	struct window		*w;
1073 	int			 status, flag;
1074 	char			*value;
1075 
1076 	if (wp == NULL)
1077 		return (NULL);
1078 	w = wp->window;
1079 
1080 	status = options_get_number(w->options, "pane-border-status");
1081 	if (status == PANE_STATUS_BOTTOM)
1082 		flag = (wp->yoff + wp->sy == w->sy - 1);
1083 	else
1084 		flag = (wp->yoff + wp->sy == w->sy);
1085 	xasprintf(&value, "%d", flag);
1086 	return (value);
1087 }
1088 
1089 /* Callback for cursor_character. */
1090 static void *
1091 format_cb_cursor_character(struct format_tree *ft)
1092 {
1093 	struct window_pane	*wp = ft->wp;
1094 	struct grid_cell	 gc;
1095 	char			*value = NULL;
1096 
1097 	if (wp == NULL)
1098 		return (NULL);
1099 
1100 	grid_view_get_cell(wp->base.grid, wp->base.cx, wp->base.cy, &gc);
1101 	if (~gc.flags & GRID_FLAG_PADDING)
1102 		xasprintf(&value, "%.*s", (int)gc.data.size, gc.data.data);
1103 	return (value);
1104 }
1105 
1106 /* Callback for mouse_word. */
1107 static void *
1108 format_cb_mouse_word(struct format_tree *ft)
1109 {
1110 	struct window_pane	*wp;
1111 	struct grid		*gd;
1112 	u_int			 x, y;
1113 	char			*s;
1114 
1115 	if (!ft->m.valid)
1116 		return (NULL);
1117 	wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1118 	if (wp == NULL)
1119 		return (NULL);
1120 	if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
1121 		return (NULL);
1122 
1123 	if (!TAILQ_EMPTY(&wp->modes)) {
1124 		if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode ||
1125 		    TAILQ_FIRST(&wp->modes)->mode == &window_view_mode)
1126 			return (s = window_copy_get_word(wp, x, y));
1127 		return (NULL);
1128 	}
1129 	gd = wp->base.grid;
1130 	return (format_grid_word(gd, x, gd->hsize + y));
1131 }
1132 
1133 /* Callback for mouse_line. */
1134 static void *
1135 format_cb_mouse_line(struct format_tree *ft)
1136 {
1137 	struct window_pane	*wp;
1138 	struct grid		*gd;
1139 	u_int			 x, y;
1140 
1141 	if (!ft->m.valid)
1142 		return (NULL);
1143 	wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1144 	if (wp == NULL)
1145 		return (NULL);
1146 	if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
1147 		return (NULL);
1148 
1149 	if (!TAILQ_EMPTY(&wp->modes)) {
1150 		if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode ||
1151 		    TAILQ_FIRST(&wp->modes)->mode == &window_view_mode)
1152 			return (window_copy_get_line(wp, y));
1153 		return (NULL);
1154 	}
1155 	gd = wp->base.grid;
1156 	return (format_grid_line(gd, gd->hsize + y));
1157 }
1158 
1159 /* Callback for alternate_on. */
1160 static void *
1161 format_cb_alternate_on(struct format_tree *ft)
1162 {
1163 	if (ft->wp != NULL) {
1164 		if (ft->wp->base.saved_grid != NULL)
1165 			return (xstrdup("1"));
1166 		return (xstrdup("0"));
1167 	}
1168 	return (NULL);
1169 }
1170 
1171 /* Callback for alternate_saved_x. */
1172 static void *
1173 format_cb_alternate_saved_x(struct format_tree *ft)
1174 {
1175 	if (ft->wp != NULL)
1176 		return (format_printf("%u", ft->wp->base.saved_cx));
1177 	return (NULL);
1178 }
1179 
1180 /* Callback for alternate_saved_y. */
1181 static void *
1182 format_cb_alternate_saved_y(struct format_tree *ft)
1183 {
1184 	if (ft->wp != NULL)
1185 		return (format_printf("%u", ft->wp->base.saved_cy));
1186 	return (NULL);
1187 }
1188 
1189 /* Callback for buffer_name. */
1190 static void *
1191 format_cb_buffer_name(struct format_tree *ft)
1192 {
1193 	if (ft->pb != NULL)
1194 		return (xstrdup(paste_buffer_name(ft->pb)));
1195 	return (NULL);
1196 }
1197 
1198 /* Callback for buffer_sample. */
1199 static void *
1200 format_cb_buffer_sample(struct format_tree *ft)
1201 {
1202 	if (ft->pb != NULL)
1203 		return (paste_make_sample(ft->pb));
1204 	return (NULL);
1205 }
1206 
1207 /* Callback for buffer_size. */
1208 static void *
1209 format_cb_buffer_size(struct format_tree *ft)
1210 {
1211 	size_t	size;
1212 
1213 	if (ft->pb != NULL) {
1214 		paste_buffer_data(ft->pb, &size);
1215 		return (format_printf("%zu", size));
1216 	}
1217 	return (NULL);
1218 }
1219 
1220 /* Callback for client_cell_height. */
1221 static void *
1222 format_cb_client_cell_height(struct format_tree *ft)
1223 {
1224 	if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED))
1225 		return (format_printf("%u", ft->c->tty.ypixel));
1226 	return (NULL);
1227 }
1228 
1229 /* Callback for client_cell_width. */
1230 static void *
1231 format_cb_client_cell_width(struct format_tree *ft)
1232 {
1233 	if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED))
1234 		return (format_printf("%u", ft->c->tty.xpixel));
1235 	return (NULL);
1236 }
1237 
1238 /* Callback for client_control_mode. */
1239 static void *
1240 format_cb_client_control_mode(struct format_tree *ft)
1241 {
1242 	if (ft->c != NULL) {
1243 		if (ft->c->flags & CLIENT_CONTROL)
1244 			return (xstrdup("1"));
1245 		return (xstrdup("0"));
1246 	}
1247 	return (NULL);
1248 }
1249 
1250 /* Callback for client_discarded. */
1251 static void *
1252 format_cb_client_discarded(struct format_tree *ft)
1253 {
1254 	if (ft->c != NULL)
1255 		return (format_printf("%zu", ft->c->discarded));
1256 	return (NULL);
1257 }
1258 
1259 /* Callback for client_flags. */
1260 static void *
1261 format_cb_client_flags(struct format_tree *ft)
1262 {
1263 	if (ft->c != NULL)
1264 		return (xstrdup(server_client_get_flags(ft->c)));
1265 	return (NULL);
1266 }
1267 
1268 /* Callback for client_height. */
1269 static void *
1270 format_cb_client_height(struct format_tree *ft)
1271 {
1272 	if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED))
1273 		return (format_printf("%u", ft->c->tty.sy));
1274 	return (NULL);
1275 }
1276 
1277 /* Callback for client_key_table. */
1278 static void *
1279 format_cb_client_key_table(struct format_tree *ft)
1280 {
1281 	if (ft->c != NULL)
1282 		return (xstrdup(ft->c->keytable->name));
1283 	return (NULL);
1284 }
1285 
1286 /* Callback for client_last_session. */
1287 static void *
1288 format_cb_client_last_session(struct format_tree *ft)
1289 {
1290 	if (ft->c != NULL &&
1291 	    ft->c->last_session != NULL &&
1292 	    session_alive(ft->c->last_session))
1293 		return (xstrdup(ft->c->last_session->name));
1294 	return (NULL);
1295 }
1296 
1297 /* Callback for client_name. */
1298 static void *
1299 format_cb_client_name(struct format_tree *ft)
1300 {
1301 	if (ft->c != NULL)
1302 		return (xstrdup(ft->c->name));
1303 	return (NULL);
1304 }
1305 
1306 /* Callback for client_pid. */
1307 static void *
1308 format_cb_client_pid(struct format_tree *ft)
1309 {
1310 	if (ft->c != NULL)
1311 		return (format_printf("%ld", (long)ft->c->pid));
1312 	return (NULL);
1313 }
1314 
1315 /* Callback for client_prefix. */
1316 static void *
1317 format_cb_client_prefix(struct format_tree *ft)
1318 {
1319 	const char	*name;
1320 
1321 	if (ft->c != NULL) {
1322 		name = server_client_get_key_table(ft->c);
1323 		if (strcmp(ft->c->keytable->name, name) == 0)
1324 			return (xstrdup("0"));
1325 		return (xstrdup("1"));
1326 	}
1327 	return (NULL);
1328 }
1329 
1330 /* Callback for client_readonly. */
1331 static void *
1332 format_cb_client_readonly(struct format_tree *ft)
1333 {
1334 	if (ft->c != NULL) {
1335 		if (ft->c->flags & CLIENT_READONLY)
1336 			return (xstrdup("1"));
1337 		return (xstrdup("0"));
1338 	}
1339 	return (NULL);
1340 }
1341 
1342 /* Callback for client_session. */
1343 static void *
1344 format_cb_client_session(struct format_tree *ft)
1345 {
1346 	if (ft->c != NULL && ft->c->session != NULL)
1347 		return (xstrdup(ft->c->session->name));
1348 	return (NULL);
1349 }
1350 
1351 /* Callback for client_termfeatures. */
1352 static void *
1353 format_cb_client_termfeatures(struct format_tree *ft)
1354 {
1355 	if (ft->c != NULL)
1356 		return (xstrdup(tty_get_features(ft->c->term_features)));
1357 	return (NULL);
1358 }
1359 
1360 /* Callback for client_termname. */
1361 static void *
1362 format_cb_client_termname(struct format_tree *ft)
1363 {
1364 	if (ft->c != NULL)
1365 		return (xstrdup(ft->c->term_name));
1366 	return (NULL);
1367 }
1368 
1369 /* Callback for client_termtype. */
1370 static void *
1371 format_cb_client_termtype(struct format_tree *ft)
1372 {
1373 	if (ft->c != NULL) {
1374 		if (ft->c->term_type == NULL)
1375 			return (xstrdup(""));
1376 		return (xstrdup(ft->c->term_type));
1377 	}
1378 	return (NULL);
1379 }
1380 
1381 /* Callback for client_tty. */
1382 static void *
1383 format_cb_client_tty(struct format_tree *ft)
1384 {
1385 	if (ft->c != NULL)
1386 		return (xstrdup(ft->c->ttyname));
1387 	return (NULL);
1388 }
1389 
1390 /* Callback for client_utf8. */
1391 static void *
1392 format_cb_client_utf8(struct format_tree *ft)
1393 {
1394 	if (ft->c != NULL) {
1395 		if (ft->c->flags & CLIENT_UTF8)
1396 			return (xstrdup("1"));
1397 		return (xstrdup("0"));
1398 	}
1399 	return (NULL);
1400 }
1401 
1402 /* Callback for client_width. */
1403 static void *
1404 format_cb_client_width(struct format_tree *ft)
1405 {
1406 	if (ft->c != NULL)
1407 		return (format_printf("%u", ft->c->tty.sx));
1408 	return (NULL);
1409 }
1410 
1411 /* Callback for client_written. */
1412 static void *
1413 format_cb_client_written(struct format_tree *ft)
1414 {
1415 	if (ft->c != NULL)
1416 		return (format_printf("%zu", ft->c->written));
1417 	return (NULL);
1418 }
1419 
1420 /* Callback for config_files. */
1421 static void *
1422 format_cb_config_files(__unused struct format_tree *ft)
1423 {
1424 	char	*s = NULL;
1425 	size_t	 slen = 0;
1426 	u_int	 i;
1427 	size_t	 n;
1428 
1429 	for (i = 0; i < cfg_nfiles; i++) {
1430 		n = strlen(cfg_files[i]) + 1;
1431 		s = xrealloc(s, slen + n + 1);
1432 		slen += xsnprintf(s + slen, n + 1, "%s,", cfg_files[i]);
1433 	}
1434 	if (s == NULL)
1435 		return (xstrdup(""));
1436 	s[slen - 1] = '\0';
1437 	return (s);
1438 }
1439 
1440 /* Callback for cursor_flag. */
1441 static void *
1442 format_cb_cursor_flag(struct format_tree *ft)
1443 {
1444 	if (ft->wp != NULL) {
1445 		if (ft->wp->base.mode & MODE_CURSOR)
1446 			return (xstrdup("1"));
1447 		return (xstrdup("0"));
1448 	}
1449 	return (NULL);
1450 }
1451 
1452 /* Callback for cursor_x. */
1453 static void *
1454 format_cb_cursor_x(struct format_tree *ft)
1455 {
1456 	if (ft->wp != NULL)
1457 		return (format_printf("%u", ft->wp->base.cx));
1458 	return (NULL);
1459 }
1460 
1461 /* Callback for cursor_y. */
1462 static void *
1463 format_cb_cursor_y(struct format_tree *ft)
1464 {
1465 	if (ft->wp != NULL)
1466 		return (format_printf("%u", ft->wp->base.cy));
1467 	return (NULL);
1468 }
1469 
1470 /* Callback for history_limit. */
1471 static void *
1472 format_cb_history_limit(struct format_tree *ft)
1473 {
1474 	if (ft->wp != NULL)
1475 		return (format_printf("%u", ft->wp->base.grid->hlimit));
1476 	return (NULL);
1477 }
1478 
1479 /* Callback for history_size. */
1480 static void *
1481 format_cb_history_size(struct format_tree *ft)
1482 {
1483 	if (ft->wp != NULL)
1484 		return (format_printf("%u", ft->wp->base.grid->hsize));
1485 	return (NULL);
1486 }
1487 
1488 /* Callback for insert_flag. */
1489 static void *
1490 format_cb_insert_flag(struct format_tree *ft)
1491 {
1492 	if (ft->wp != NULL) {
1493 		if (ft->wp->base.mode & MODE_INSERT)
1494 			return (xstrdup("1"));
1495 		return (xstrdup("0"));
1496 	}
1497 	return (NULL);
1498 }
1499 
1500 /* Callback for keypad_cursor_flag. */
1501 static void *
1502 format_cb_keypad_cursor_flag(struct format_tree *ft)
1503 {
1504 	if (ft->wp != NULL) {
1505 		if (ft->wp->base.mode & MODE_KCURSOR)
1506 			return (xstrdup("1"));
1507 		return (xstrdup("0"));
1508 	}
1509 	return (NULL);
1510 }
1511 
1512 /* Callback for keypad_flag. */
1513 static void *
1514 format_cb_keypad_flag(struct format_tree *ft)
1515 {
1516 	if (ft->wp != NULL) {
1517 		if (ft->wp->base.mode & MODE_KKEYPAD)
1518 			return (xstrdup("1"));
1519 		return (xstrdup("0"));
1520 	}
1521 	return (NULL);
1522 }
1523 
1524 /* Callback for mouse_all_flag. */
1525 static void *
1526 format_cb_mouse_all_flag(struct format_tree *ft)
1527 {
1528 	if (ft->wp != NULL) {
1529 		if (ft->wp->base.mode & MODE_MOUSE_ALL)
1530 			return (xstrdup("1"));
1531 		return (xstrdup("0"));
1532 	}
1533 	return (NULL);
1534 }
1535 
1536 /* Callback for mouse_any_flag. */
1537 static void *
1538 format_cb_mouse_any_flag(struct format_tree *ft)
1539 {
1540 	if (ft->wp != NULL) {
1541 		if (ft->wp->base.mode & ALL_MOUSE_MODES)
1542 			return (xstrdup("1"));
1543 		return (xstrdup("0"));
1544 	}
1545 	return (NULL);
1546 }
1547 
1548 /* Callback for mouse_button_flag. */
1549 static void *
1550 format_cb_mouse_button_flag(struct format_tree *ft)
1551 {
1552 	if (ft->wp != NULL) {
1553 		if (ft->wp->base.mode & MODE_MOUSE_BUTTON)
1554 			return (xstrdup("1"));
1555 		return (xstrdup("0"));
1556 	}
1557 	return (NULL);
1558 }
1559 
1560 /* Callback for mouse_pane. */
1561 static void *
1562 format_cb_mouse_pane(struct format_tree *ft)
1563 {
1564 	struct window_pane	*wp;
1565 
1566 	if (ft->m.valid) {
1567 		wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1568 		if (wp != NULL)
1569 			return (format_printf("%%%u", wp->id));
1570 		return (NULL);
1571 	}
1572 	return (NULL);
1573 }
1574 
1575 /* Callback for mouse_sgr_flag. */
1576 static void *
1577 format_cb_mouse_sgr_flag(struct format_tree *ft)
1578 {
1579 	if (ft->wp != NULL) {
1580 		if (ft->wp->base.mode & MODE_MOUSE_SGR)
1581 			return (xstrdup("1"));
1582 		return (xstrdup("0"));
1583 	}
1584 	return (NULL);
1585 }
1586 
1587 /* Callback for mouse_standard_flag. */
1588 static void *
1589 format_cb_mouse_standard_flag(struct format_tree *ft)
1590 {
1591 	if (ft->wp != NULL) {
1592 		if (ft->wp->base.mode & MODE_MOUSE_STANDARD)
1593 			return (xstrdup("1"));
1594 		return (xstrdup("0"));
1595 	}
1596 	return (NULL);
1597 }
1598 
1599 /* Callback for mouse_utf8_flag. */
1600 static void *
1601 format_cb_mouse_utf8_flag(struct format_tree *ft)
1602 {
1603 	if (ft->wp != NULL) {
1604 		if (ft->wp->base.mode & MODE_MOUSE_UTF8)
1605 			return (xstrdup("1"));
1606 		return (xstrdup("0"));
1607 	}
1608 	return (NULL);
1609 }
1610 
1611 /* Callback for mouse_x. */
1612 static void *
1613 format_cb_mouse_x(struct format_tree *ft)
1614 {
1615 	struct window_pane	*wp;
1616 	u_int			 x, y;
1617 
1618 	if (!ft->m.valid)
1619 		return (NULL);
1620 	wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1621 	if (wp != NULL && cmd_mouse_at(wp, &ft->m, &x, &y, 0) == 0)
1622 		return (format_printf("%u", x));
1623 	if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED)) {
1624 		if (ft->m.statusat == 0 && ft->m.y < ft->m.statuslines)
1625 			return (format_printf("%u", ft->m.x));
1626 		if (ft->m.statusat > 0 && ft->m.y >= (u_int)ft->m.statusat)
1627 			return (format_printf("%u", ft->m.x));
1628 	}
1629 	return (NULL);
1630 }
1631 
1632 /* Callback for mouse_y. */
1633 static void *
1634 format_cb_mouse_y(struct format_tree *ft)
1635 {
1636 	struct window_pane	*wp;
1637 	u_int			 x, y;
1638 
1639 	if (!ft->m.valid)
1640 		return (NULL);
1641 	wp = cmd_mouse_pane(&ft->m, NULL, NULL);
1642 	if (wp != NULL && cmd_mouse_at(wp, &ft->m, &x, &y, 0) == 0)
1643 		return (format_printf("%u", y));
1644 	if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED)) {
1645 		if (ft->m.statusat == 0 && ft->m.y < ft->m.statuslines)
1646 			return (format_printf("%u", ft->m.y));
1647 		if (ft->m.statusat > 0 && ft->m.y >= (u_int)ft->m.statusat)
1648 			return (format_printf("%u", ft->m.y - ft->m.statusat));
1649 	}
1650 	return (NULL);
1651 }
1652 
1653 /* Callback for origin_flag. */
1654 static void *
1655 format_cb_origin_flag(struct format_tree *ft)
1656 {
1657 	if (ft->wp != NULL) {
1658 		if (ft->wp->base.mode & MODE_ORIGIN)
1659 			return (xstrdup("1"));
1660 		return (xstrdup("0"));
1661 	}
1662 	return (NULL);
1663 }
1664 
1665 /* Callback for pane_active. */
1666 static void *
1667 format_cb_pane_active(struct format_tree *ft)
1668 {
1669 	if (ft->wp != NULL) {
1670 		if (ft->wp == ft->wp->window->active)
1671 			return (xstrdup("1"));
1672 		return (xstrdup("0"));
1673 	}
1674 	return (NULL);
1675 }
1676 
1677 /* Callback for pane_at_left. */
1678 static void *
1679 format_cb_pane_at_left(struct format_tree *ft)
1680 {
1681 	if (ft->wp != NULL) {
1682 		if (ft->wp->xoff == 0)
1683 			return (xstrdup("1"));
1684 		return (xstrdup("0"));
1685 	}
1686 	return (NULL);
1687 }
1688 
1689 /* Callback for pane_at_right. */
1690 static void *
1691 format_cb_pane_at_right(struct format_tree *ft)
1692 {
1693 	if (ft->wp != NULL) {
1694 		if (ft->wp->xoff + ft->wp->sx == ft->wp->window->sx)
1695 			return (xstrdup("1"));
1696 		return (xstrdup("0"));
1697 	}
1698 	return (NULL);
1699 }
1700 
1701 /* Callback for pane_bottom. */
1702 static void *
1703 format_cb_pane_bottom(struct format_tree *ft)
1704 {
1705 	if (ft->wp != NULL)
1706 		return (format_printf("%u", ft->wp->yoff + ft->wp->sy - 1));
1707 	return (NULL);
1708 }
1709 
1710 /* Callback for pane_dead. */
1711 static void *
1712 format_cb_pane_dead(struct format_tree *ft)
1713 {
1714 	if (ft->wp != NULL) {
1715 		if (ft->wp->fd == -1)
1716 			return (xstrdup("1"));
1717 		return (xstrdup("0"));
1718 	}
1719 	return (NULL);
1720 }
1721 
1722 /* Callback for pane_dead_status. */
1723 static void *
1724 format_cb_pane_dead_status(struct format_tree *ft)
1725 {
1726 	struct window_pane	*wp = ft->wp;
1727 
1728 	if (wp != NULL) {
1729 		if ((wp->flags & PANE_STATUSREADY) && WIFEXITED(wp->status))
1730 			return (format_printf("%d", WEXITSTATUS(wp->status)));
1731 		return (NULL);
1732 	}
1733 	return (NULL);
1734 }
1735 
1736 /* Callback for pane_format. */
1737 static void *
1738 format_cb_pane_format(struct format_tree *ft)
1739 {
1740 	if (ft->type == FORMAT_TYPE_PANE)
1741 		return (xstrdup("1"));
1742 	return (xstrdup("0"));
1743 }
1744 
1745 /* Callback for pane_height. */
1746 static void *
1747 format_cb_pane_height(struct format_tree *ft)
1748 {
1749 	if (ft->wp != NULL)
1750 		return (format_printf("%u", ft->wp->sy));
1751 	return (NULL);
1752 }
1753 
1754 /* Callback for pane_id. */
1755 static void *
1756 format_cb_pane_id(struct format_tree *ft)
1757 {
1758 	if (ft->wp != NULL)
1759 		return (format_printf("%%%u", ft->wp->id));
1760 	return (NULL);
1761 }
1762 
1763 /* Callback for pane_index. */
1764 static void *
1765 format_cb_pane_index(struct format_tree *ft)
1766 {
1767 	u_int	idx;
1768 
1769 	if (ft->wp != NULL && window_pane_index(ft->wp, &idx) == 0)
1770 		return (format_printf("%u", idx));
1771 	return (NULL);
1772 }
1773 
1774 /* Callback for pane_input_off. */
1775 static void *
1776 format_cb_pane_input_off(struct format_tree *ft)
1777 {
1778 	if (ft->wp != NULL) {
1779 		if (ft->wp->flags & PANE_INPUTOFF)
1780 			return (xstrdup("1"));
1781 		return (xstrdup("0"));
1782 	}
1783 	return (NULL);
1784 }
1785 
1786 /* Callback for pane_last. */
1787 static void *
1788 format_cb_pane_last(struct format_tree *ft)
1789 {
1790 	if (ft->wp != NULL) {
1791 		if (ft->wp == ft->wp->window->last)
1792 			return (xstrdup("1"));
1793 		return (xstrdup("0"));
1794 	}
1795 	return (NULL);
1796 }
1797 
1798 /* Callback for pane_left. */
1799 static void *
1800 format_cb_pane_left(struct format_tree *ft)
1801 {
1802 	if (ft->wp != NULL)
1803 		return (format_printf("%u", ft->wp->xoff));
1804 	return (NULL);
1805 }
1806 
1807 /* Callback for pane_marked. */
1808 static void *
1809 format_cb_pane_marked(struct format_tree *ft)
1810 {
1811 	if (ft->wp != NULL) {
1812 		if (server_check_marked() && marked_pane.wp == ft->wp)
1813 			return (xstrdup("1"));
1814 		return (xstrdup("0"));
1815 	}
1816 	return (NULL);
1817 }
1818 
1819 /* Callback for pane_marked_set. */
1820 static void *
1821 format_cb_pane_marked_set(struct format_tree *ft)
1822 {
1823 	if (ft->wp != NULL) {
1824 		if (server_check_marked())
1825 			return (xstrdup("1"));
1826 		return (xstrdup("0"));
1827 	}
1828 	return (NULL);
1829 }
1830 
1831 /* Callback for pane_mode. */
1832 static void *
1833 format_cb_pane_mode(struct format_tree *ft)
1834 {
1835 	struct window_mode_entry	*wme;
1836 
1837 	if (ft->wp != NULL) {
1838 		wme = TAILQ_FIRST(&ft->wp->modes);
1839 		if (wme != NULL)
1840 			return (xstrdup(wme->mode->name));
1841 		return (NULL);
1842 	}
1843 	return (NULL);
1844 }
1845 
1846 /* Callback for pane_path. */
1847 static void *
1848 format_cb_pane_path(struct format_tree *ft)
1849 {
1850 	if (ft->wp != NULL) {
1851 		if (ft->wp->base.path == NULL)
1852 			return (xstrdup(""));
1853 		return (xstrdup(ft->wp->base.path));
1854 	}
1855 	return (NULL);
1856 }
1857 
1858 /* Callback for pane_pid. */
1859 static void *
1860 format_cb_pane_pid(struct format_tree *ft)
1861 {
1862 	if (ft->wp != NULL)
1863 		return (format_printf("%ld", (long)ft->wp->pid));
1864 	return (NULL);
1865 }
1866 
1867 /* Callback for pane_pipe. */
1868 static void *
1869 format_cb_pane_pipe(struct format_tree *ft)
1870 {
1871 	if (ft->wp != NULL) {
1872 		if (ft->wp->pipe_fd != -1)
1873 			return (xstrdup("1"));
1874 		return (xstrdup("0"));
1875 	}
1876 	return (NULL);
1877 }
1878 
1879 /* Callback for pane_right. */
1880 static void *
1881 format_cb_pane_right(struct format_tree *ft)
1882 {
1883 	if (ft->wp != NULL)
1884 		return (format_printf("%u", ft->wp->xoff + ft->wp->sx - 1));
1885 	return (NULL);
1886 }
1887 
1888 /* Callback for pane_search_string. */
1889 static void *
1890 format_cb_pane_search_string(struct format_tree *ft)
1891 {
1892 	if (ft->wp != NULL) {
1893 		if (ft->wp->searchstr == NULL)
1894 			return (xstrdup(""));
1895 		return (xstrdup(ft->wp->searchstr));
1896 	}
1897 	return (NULL);
1898 }
1899 
1900 /* Callback for pane_synchronized. */
1901 static void *
1902 format_cb_pane_synchronized(struct format_tree *ft)
1903 {
1904 	if (ft->wp != NULL) {
1905 		if (options_get_number(ft->wp->options, "synchronize-panes"))
1906 			return (xstrdup("1"));
1907 		return (xstrdup("0"));
1908 	}
1909 	return (NULL);
1910 }
1911 
1912 /* Callback for pane_title. */
1913 static void *
1914 format_cb_pane_title(struct format_tree *ft)
1915 {
1916 	if (ft->wp != NULL)
1917 		return (xstrdup(ft->wp->base.title));
1918 	return (NULL);
1919 }
1920 
1921 /* Callback for pane_top. */
1922 static void *
1923 format_cb_pane_top(struct format_tree *ft)
1924 {
1925 	if (ft->wp != NULL)
1926 		return (format_printf("%u", ft->wp->yoff));
1927 	return (NULL);
1928 }
1929 
1930 /* Callback for pane_tty. */
1931 static void *
1932 format_cb_pane_tty(struct format_tree *ft)
1933 {
1934 	if (ft->wp != NULL)
1935 		return (xstrdup(ft->wp->tty));
1936 	return (NULL);
1937 }
1938 
1939 /* Callback for pane_width. */
1940 static void *
1941 format_cb_pane_width(struct format_tree *ft)
1942 {
1943 	if (ft->wp != NULL)
1944 		return (format_printf("%u", ft->wp->sx));
1945 	return (NULL);
1946 }
1947 
1948 /* Callback for scroll_region_lower. */
1949 static void *
1950 format_cb_scroll_region_lower(struct format_tree *ft)
1951 {
1952 	if (ft->wp != NULL)
1953 		return (format_printf("%u", ft->wp->base.rlower));
1954 	return (NULL);
1955 }
1956 
1957 /* Callback for scroll_region_upper. */
1958 static void *
1959 format_cb_scroll_region_upper(struct format_tree *ft)
1960 {
1961 	if (ft->wp != NULL)
1962 		return (format_printf("%u", ft->wp->base.rupper));
1963 	return (NULL);
1964 }
1965 
1966 /* Callback for session_attached. */
1967 static void *
1968 format_cb_session_attached(struct format_tree *ft)
1969 {
1970 	if (ft->s != NULL)
1971 		return (format_printf("%u", ft->s->attached));
1972 	return (NULL);
1973 }
1974 
1975 /* Callback for session_format. */
1976 static void *
1977 format_cb_session_format(struct format_tree *ft)
1978 {
1979 	if (ft->type == FORMAT_TYPE_SESSION)
1980 		return (xstrdup("1"));
1981 	return (xstrdup("0"));
1982 }
1983 
1984 /* Callback for session_group. */
1985 static void *
1986 format_cb_session_group(struct format_tree *ft)
1987 {
1988 	struct session_group	*sg;
1989 
1990 	if (ft->s != NULL && (sg = session_group_contains(ft->s)) != NULL)
1991 		return (xstrdup(sg->name));
1992 	return (NULL);
1993 }
1994 
1995 /* Callback for session_group_attached. */
1996 static void *
1997 format_cb_session_group_attached(struct format_tree *ft)
1998 {
1999 	struct session_group	*sg;
2000 
2001 	if (ft->s != NULL && (sg = session_group_contains(ft->s)) != NULL)
2002 		return (format_printf("%u", session_group_attached_count (sg)));
2003 	return (NULL);
2004 }
2005 
2006 /* Callback for session_group_many_attached. */
2007 static void *
2008 format_cb_session_group_many_attached(struct format_tree *ft)
2009 {
2010 	struct session_group	*sg;
2011 
2012 	if (ft->s != NULL && (sg = session_group_contains(ft->s)) != NULL) {
2013 		if (session_group_attached_count (sg) > 1)
2014 			return (xstrdup("1"));
2015 		return (xstrdup("0"));
2016 	}
2017 	return (NULL);
2018 }
2019 
2020 /* Callback for session_group_size. */
2021 static void *
2022 format_cb_session_group_size(struct format_tree *ft)
2023 {
2024 	struct session_group	*sg;
2025 
2026 	if (ft->s != NULL && (sg = session_group_contains(ft->s)) != NULL)
2027 		return (format_printf("%u", session_group_count (sg)));
2028 	return (NULL);
2029 }
2030 
2031 /* Callback for session_grouped. */
2032 static void *
2033 format_cb_session_grouped(struct format_tree *ft)
2034 {
2035 	if (ft->s != NULL) {
2036 		if (session_group_contains(ft->s) != NULL)
2037 			return (xstrdup("1"));
2038 		return (xstrdup("0"));
2039 	}
2040 	return (NULL);
2041 }
2042 
2043 /* Callback for session_id. */
2044 static void *
2045 format_cb_session_id(struct format_tree *ft)
2046 {
2047 	if (ft->s != NULL)
2048 		return (format_printf("$%u", ft->s->id));
2049 	return (NULL);
2050 }
2051 
2052 /* Callback for session_many_attached. */
2053 static void *
2054 format_cb_session_many_attached(struct format_tree *ft)
2055 {
2056 	if (ft->s != NULL) {
2057 		if (ft->s->attached > 1)
2058 			return (xstrdup("1"));
2059 		return (xstrdup("0"));
2060 	}
2061 	return (NULL);
2062 }
2063 
2064 /* Callback for session_marked. */
2065 static void *
2066 format_cb_session_marked(struct format_tree *ft)
2067 {
2068 	if (ft->s != NULL) {
2069 		if (server_check_marked() && marked_pane.s == ft->s)
2070 			return (xstrdup("1"));
2071 		return (xstrdup("0"));
2072 	}
2073 	return (NULL);
2074 }
2075 
2076 /* Callback for session_name. */
2077 static void *
2078 format_cb_session_name(struct format_tree *ft)
2079 {
2080 	if (ft->s != NULL)
2081 		return (xstrdup(ft->s->name));
2082 	return (NULL);
2083 }
2084 
2085 /* Callback for session_path. */
2086 static void *
2087 format_cb_session_path(struct format_tree *ft)
2088 {
2089 	if (ft->s != NULL)
2090 		return (xstrdup(ft->s->cwd));
2091 	return (NULL);
2092 }
2093 
2094 /* Callback for session_windows. */
2095 static void *
2096 format_cb_session_windows(struct format_tree *ft)
2097 {
2098 	if (ft->s != NULL)
2099 		return (format_printf("%u", winlink_count(&ft->s->windows)));
2100 	return (NULL);
2101 }
2102 
2103 /* Callback for socket_path. */
2104 static void *
2105 format_cb_socket_path(__unused struct format_tree *ft)
2106 {
2107 	return (xstrdup(socket_path));
2108 }
2109 
2110 /* Callback for version. */
2111 static void *
2112 format_cb_version(__unused struct format_tree *ft)
2113 {
2114 	return (xstrdup(getversion()));
2115 }
2116 
2117 /* Callback for active_window_index. */
2118 static void *
2119 format_cb_active_window_index(struct format_tree *ft)
2120 {
2121 	if (ft->s != NULL)
2122 		return (format_printf("%u", ft->s->curw->idx));
2123 	return (NULL);
2124 }
2125 
2126 /* Callback for last_window_index. */
2127 static void *
2128 format_cb_last_window_index(struct format_tree *ft)
2129 {
2130 	struct winlink	*wl;
2131 
2132 	if (ft->s != NULL) {
2133 		wl = RB_MAX(winlinks, &ft->s->windows);
2134 		return (format_printf("%u", wl->idx));
2135 	}
2136 	return (NULL);
2137 }
2138 
2139 /* Callback for window_active. */
2140 static void *
2141 format_cb_window_active(struct format_tree *ft)
2142 {
2143 	if (ft->wl != NULL) {
2144 		if (ft->wl == ft->wl->session->curw)
2145 			return (xstrdup("1"));
2146 		return (xstrdup("0"));
2147 	}
2148 	return (NULL);
2149 }
2150 
2151 /* Callback for window_activity_flag. */
2152 static void *
2153 format_cb_window_activity_flag(struct format_tree *ft)
2154 {
2155 	if (ft->wl != NULL) {
2156 		if (ft->wl->flags & WINLINK_ACTIVITY)
2157 			return (xstrdup("1"));
2158 		return (xstrdup("0"));
2159 	}
2160 	return (NULL);
2161 }
2162 
2163 /* Callback for window_bell_flag. */
2164 static void *
2165 format_cb_window_bell_flag(struct format_tree *ft)
2166 {
2167 	if (ft->wl != NULL) {
2168 		if (ft->wl->flags & WINLINK_BELL)
2169 			return (xstrdup("1"));
2170 		return (xstrdup("0"));
2171 	}
2172 	return (NULL);
2173 }
2174 
2175 /* Callback for window_bigger. */
2176 static void *
2177 format_cb_window_bigger(struct format_tree *ft)
2178 {
2179 	u_int	ox, oy, sx, sy;
2180 
2181 	if (ft->c != NULL) {
2182 		if (tty_window_offset(&ft->c->tty, &ox, &oy, &sx, &sy))
2183 			return (xstrdup("1"));
2184 		return (xstrdup("0"));
2185 	}
2186 	return (NULL);
2187 }
2188 
2189 /* Callback for window_cell_height. */
2190 static void *
2191 format_cb_window_cell_height(struct format_tree *ft)
2192 {
2193 	if (ft->w != NULL)
2194 		return (format_printf("%u", ft->w->ypixel));
2195 	return (NULL);
2196 }
2197 
2198 /* Callback for window_cell_width. */
2199 static void *
2200 format_cb_window_cell_width(struct format_tree *ft)
2201 {
2202 	if (ft->w != NULL)
2203 		return (format_printf("%u", ft->w->xpixel));
2204 	return (NULL);
2205 }
2206 
2207 /* Callback for window_end_flag. */
2208 static void *
2209 format_cb_window_end_flag(struct format_tree *ft)
2210 {
2211 	if (ft->wl != NULL) {
2212 		if (ft->wl == RB_MAX(winlinks, &ft->wl->session->windows))
2213 			return (xstrdup("1"));
2214 		return (xstrdup("0"));
2215 	}
2216 	return (NULL);
2217 }
2218 
2219 /* Callback for window_flags. */
2220 static void *
2221 format_cb_window_flags(struct format_tree *ft)
2222 {
2223 	if (ft->wl != NULL)
2224 		return (xstrdup(window_printable_flags(ft->wl, 1)));
2225 	return (NULL);
2226 }
2227 
2228 /* Callback for window_format. */
2229 static void *
2230 format_cb_window_format(struct format_tree *ft)
2231 {
2232 	if (ft->type == FORMAT_TYPE_WINDOW)
2233 		return (xstrdup("1"));
2234 	return (xstrdup("0"));
2235 }
2236 
2237 /* Callback for window_height. */
2238 static void *
2239 format_cb_window_height(struct format_tree *ft)
2240 {
2241 	if (ft->w != NULL)
2242 		return (format_printf("%u", ft->w->sy));
2243 	return (NULL);
2244 }
2245 
2246 /* Callback for window_id. */
2247 static void *
2248 format_cb_window_id(struct format_tree *ft)
2249 {
2250 	if (ft->w != NULL)
2251 		return (format_printf("@%u", ft->w->id));
2252 	return (NULL);
2253 }
2254 
2255 /* Callback for window_index. */
2256 static void *
2257 format_cb_window_index(struct format_tree *ft)
2258 {
2259 	if (ft->wl != NULL)
2260 		return (format_printf("%d", ft->wl->idx));
2261 	return (NULL);
2262 }
2263 
2264 /* Callback for window_last_flag. */
2265 static void *
2266 format_cb_window_last_flag(struct format_tree *ft)
2267 {
2268 	if (ft->wl != NULL) {
2269 		if (ft->wl == TAILQ_FIRST(&ft->wl->session->lastw))
2270 			return (xstrdup("1"));
2271 		return (xstrdup("0"));
2272 	}
2273 	return (NULL);
2274 }
2275 
2276 /* Callback for window_linked. */
2277 static void *
2278 format_cb_window_linked(struct format_tree *ft)
2279 {
2280 	if (ft->wl != NULL) {
2281 		if (session_is_linked(ft->wl->session, ft->wl->window))
2282 			return (xstrdup("1"));
2283 		return (xstrdup("0"));
2284 	}
2285 	return (NULL);
2286 }
2287 
2288 /* Callback for window_linked_sessions. */
2289 static void *
2290 format_cb_window_linked_sessions(struct format_tree *ft)
2291 {
2292 	if (ft->wl != NULL)
2293 		return (format_printf("%u", ft->wl->window->references));
2294 	return (NULL);
2295 }
2296 
2297 /* Callback for window_marked_flag. */
2298 static void *
2299 format_cb_window_marked_flag(struct format_tree *ft)
2300 {
2301 	if (ft->wl != NULL) {
2302 		if (server_check_marked() && marked_pane.wl == ft->wl)
2303 			return (xstrdup("1"));
2304 		return (xstrdup("0"));
2305 	}
2306 	return (NULL);
2307 }
2308 
2309 /* Callback for window_name. */
2310 static void *
2311 format_cb_window_name(struct format_tree *ft)
2312 {
2313 	if (ft->w != NULL)
2314 		return (format_printf("%s", ft->w->name));
2315 	return (NULL);
2316 }
2317 
2318 /* Callback for window_offset_x. */
2319 static void *
2320 format_cb_window_offset_x(struct format_tree *ft)
2321 {
2322 	u_int	ox, oy, sx, sy;
2323 
2324 	if (ft->c != NULL) {
2325 		if (tty_window_offset(&ft->c->tty, &ox, &oy, &sx, &sy))
2326 			return (format_printf("%u", ox));
2327 		return (NULL);
2328 	}
2329 	return (NULL);
2330 }
2331 
2332 /* Callback for window_offset_y. */
2333 static void *
2334 format_cb_window_offset_y(struct format_tree *ft)
2335 {
2336 	u_int	ox, oy, sx, sy;
2337 
2338 	if (ft->c != NULL) {
2339 		if (tty_window_offset(&ft->c->tty, &ox, &oy, &sx, &sy))
2340 			return (format_printf("%u", oy));
2341 		return (NULL);
2342 	}
2343 	return (NULL);
2344 }
2345 
2346 /* Callback for window_panes. */
2347 static void *
2348 format_cb_window_panes(struct format_tree *ft)
2349 {
2350 	if (ft->w != NULL)
2351 		return (format_printf("%u", window_count_panes(ft->w)));
2352 	return (NULL);
2353 }
2354 
2355 /* Callback for window_raw_flags. */
2356 static void *
2357 format_cb_window_raw_flags(struct format_tree *ft)
2358 {
2359 	if (ft->wl != NULL)
2360 		return (xstrdup(window_printable_flags(ft->wl, 0)));
2361 	return (NULL);
2362 }
2363 
2364 /* Callback for window_silence_flag. */
2365 static void *
2366 format_cb_window_silence_flag(struct format_tree *ft)
2367 {
2368 	if (ft->wl != NULL) {
2369 		if (ft->wl->flags & WINLINK_SILENCE)
2370 			return (xstrdup("1"));
2371 		return (xstrdup("0"));
2372 	}
2373 	return (NULL);
2374 }
2375 
2376 /* Callback for window_start_flag. */
2377 static void *
2378 format_cb_window_start_flag(struct format_tree *ft)
2379 {
2380 	if (ft->wl != NULL) {
2381 		if (ft->wl == RB_MIN(winlinks, &ft->wl->session->windows))
2382 			return (xstrdup("1"));
2383 		return (xstrdup("0"));
2384 	}
2385 	return (NULL);
2386 }
2387 
2388 /* Callback for window_width. */
2389 static void *
2390 format_cb_window_width(struct format_tree *ft)
2391 {
2392 	if (ft->w != NULL)
2393 		return (format_printf("%u", ft->w->sx));
2394 	return (NULL);
2395 }
2396 
2397 /* Callback for window_zoomed_flag. */
2398 static void *
2399 format_cb_window_zoomed_flag(struct format_tree *ft)
2400 {
2401 	if (ft->w != NULL) {
2402 		if (ft->w->flags & WINDOW_ZOOMED)
2403 			return (xstrdup("1"));
2404 		return (xstrdup("0"));
2405 	}
2406 	return (NULL);
2407 }
2408 
2409 /* Callback for wrap_flag. */
2410 static void *
2411 format_cb_wrap_flag(struct format_tree *ft)
2412 {
2413 	if (ft->wp != NULL) {
2414 		if (ft->wp->base.mode & MODE_WRAP)
2415 			return (xstrdup("1"));
2416 		return (xstrdup("0"));
2417 	}
2418 	return (NULL);
2419 }
2420 
2421 /* Callback for buffer_created. */
2422 static void *
2423 format_cb_buffer_created(struct format_tree *ft)
2424 {
2425 	static struct timeval	 tv;
2426 
2427 	if (ft->pb != NULL) {
2428 		timerclear(&tv);
2429 		tv.tv_sec = paste_buffer_created(ft->pb);
2430 		return (&tv);
2431 	}
2432 	return (NULL);
2433 }
2434 
2435 /* Callback for client_activity. */
2436 static void *
2437 format_cb_client_activity(struct format_tree *ft)
2438 {
2439 	if (ft->c != NULL)
2440 		return (&ft->c->activity_time);
2441 	return (NULL);
2442 }
2443 
2444 /* Callback for client_created. */
2445 static void *
2446 format_cb_client_created(struct format_tree *ft)
2447 {
2448 	if (ft->c != NULL)
2449 		return (&ft->c->creation_time);
2450 	return (NULL);
2451 }
2452 
2453 /* Callback for session_activity. */
2454 static void *
2455 format_cb_session_activity(struct format_tree *ft)
2456 {
2457 	if (ft->s != NULL)
2458 		return (&ft->s->activity_time);
2459 	return (NULL);
2460 }
2461 
2462 /* Callback for session_created. */
2463 static void *
2464 format_cb_session_created(struct format_tree *ft)
2465 {
2466 	if (ft->s != NULL)
2467 		return (&ft->s->creation_time);
2468 	return (NULL);
2469 }
2470 
2471 /* Callback for session_last_attached. */
2472 static void *
2473 format_cb_session_last_attached(struct format_tree *ft)
2474 {
2475 	if (ft->s != NULL)
2476 		return (&ft->s->last_attached_time);
2477 	return (NULL);
2478 }
2479 
2480 /* Callback for start_time. */
2481 static void *
2482 format_cb_start_time(__unused struct format_tree *ft)
2483 {
2484 	return (&start_time);
2485 }
2486 
2487 /* Callback for window_activity. */
2488 static void *
2489 format_cb_window_activity(struct format_tree *ft)
2490 {
2491 	if (ft->w != NULL)
2492 		return (&ft->w->activity_time);
2493 	return (NULL);
2494 }
2495 
2496 /* Callback for buffer_mode_format, */
2497 static void *
2498 format_cb_buffer_mode_format(__unused struct format_tree *ft)
2499 {
2500 	return (xstrdup(window_buffer_mode.default_format));
2501 }
2502 
2503 /* Callback for client_mode_format, */
2504 static void *
2505 format_cb_client_mode_format(__unused struct format_tree *ft)
2506 {
2507 	return (xstrdup(window_client_mode.default_format));
2508 }
2509 
2510 /* Callback for tree_mode_format, */
2511 static void *
2512 format_cb_tree_mode_format(__unused struct format_tree *ft)
2513 {
2514 	return (xstrdup(window_tree_mode.default_format));
2515 }
2516 
2517 /* Format table type. */
2518 enum format_table_type {
2519 	FORMAT_TABLE_STRING,
2520 	FORMAT_TABLE_TIME
2521 };
2522 
2523 /* Format table entry. */
2524 struct format_table_entry {
2525 	const char		*key;
2526 	enum format_table_type	 type;
2527 	format_cb		 cb;
2528 };
2529 
2530 /*
2531  * Format table. Default format variables (that are almost always in the tree
2532  * and where the value is expanded by a callback in this file) are listed here.
2533  * Only variables which are added by the caller go into the tree.
2534  */
2535 static const struct format_table_entry format_table[] = {
2536 	{ "active_window_index", FORMAT_TABLE_STRING,
2537 	  format_cb_active_window_index
2538 	},
2539 	{ "alternate_on", FORMAT_TABLE_STRING,
2540 	  format_cb_alternate_on
2541 	},
2542 	{ "alternate_saved_x", FORMAT_TABLE_STRING,
2543 	  format_cb_alternate_saved_x
2544 	},
2545 	{ "alternate_saved_y", FORMAT_TABLE_STRING,
2546 	  format_cb_alternate_saved_y
2547 	},
2548 	{ "buffer_created", FORMAT_TABLE_TIME,
2549 	  format_cb_buffer_created
2550 	},
2551 	{ "buffer_mode_format", FORMAT_TABLE_STRING,
2552 	  format_cb_buffer_mode_format
2553 	},
2554 	{ "buffer_name", FORMAT_TABLE_STRING,
2555 	  format_cb_buffer_name
2556 	},
2557 	{ "buffer_sample", FORMAT_TABLE_STRING,
2558 	  format_cb_buffer_sample
2559 	},
2560 	{ "buffer_size", FORMAT_TABLE_STRING,
2561 	  format_cb_buffer_size
2562 	},
2563 	{ "client_activity", FORMAT_TABLE_TIME,
2564 	  format_cb_client_activity
2565 	},
2566 	{ "client_cell_height", FORMAT_TABLE_STRING,
2567 	  format_cb_client_cell_height
2568 	},
2569 	{ "client_cell_width", FORMAT_TABLE_STRING,
2570 	  format_cb_client_cell_width
2571 	},
2572 	{ "client_control_mode", FORMAT_TABLE_STRING,
2573 	  format_cb_client_control_mode
2574 	},
2575 	{ "client_created", FORMAT_TABLE_TIME,
2576 	  format_cb_client_created
2577 	},
2578 	{ "client_discarded", FORMAT_TABLE_STRING,
2579 	  format_cb_client_discarded
2580 	},
2581 	{ "client_flags", FORMAT_TABLE_STRING,
2582 	  format_cb_client_flags
2583 	},
2584 	{ "client_height", FORMAT_TABLE_STRING,
2585 	  format_cb_client_height
2586 	},
2587 	{ "client_key_table", FORMAT_TABLE_STRING,
2588 	  format_cb_client_key_table
2589 	},
2590 	{ "client_last_session", FORMAT_TABLE_STRING,
2591 	  format_cb_client_last_session
2592 	},
2593 	{ "client_mode_format", FORMAT_TABLE_STRING,
2594 	  format_cb_client_mode_format
2595 	},
2596 	{ "client_name", FORMAT_TABLE_STRING,
2597 	  format_cb_client_name
2598 	},
2599 	{ "client_pid", FORMAT_TABLE_STRING,
2600 	  format_cb_client_pid
2601 	},
2602 	{ "client_prefix", FORMAT_TABLE_STRING,
2603 	  format_cb_client_prefix
2604 	},
2605 	{ "client_readonly", FORMAT_TABLE_STRING,
2606 	  format_cb_client_readonly
2607 	},
2608 	{ "client_session", FORMAT_TABLE_STRING,
2609 	  format_cb_client_session
2610 	},
2611 	{ "client_termfeatures", FORMAT_TABLE_STRING,
2612 	  format_cb_client_termfeatures
2613 	},
2614 	{ "client_termname", FORMAT_TABLE_STRING,
2615 	  format_cb_client_termname
2616 	},
2617 	{ "client_termtype", FORMAT_TABLE_STRING,
2618 	  format_cb_client_termtype
2619 	},
2620 	{ "client_tty", FORMAT_TABLE_STRING,
2621 	  format_cb_client_tty
2622 	},
2623 	{ "client_utf8", FORMAT_TABLE_STRING,
2624 	  format_cb_client_utf8
2625 	},
2626 	{ "client_width", FORMAT_TABLE_STRING,
2627 	  format_cb_client_width
2628 	},
2629 	{ "client_written", FORMAT_TABLE_STRING,
2630 	  format_cb_client_written
2631 	},
2632 	{ "config_files", FORMAT_TABLE_STRING,
2633 	  format_cb_config_files
2634 	},
2635 	{ "cursor_character", FORMAT_TABLE_STRING,
2636 	  format_cb_cursor_character
2637 	},
2638 	{ "cursor_flag", FORMAT_TABLE_STRING,
2639 	  format_cb_cursor_flag
2640 	},
2641 	{ "cursor_x", FORMAT_TABLE_STRING,
2642 	  format_cb_cursor_x
2643 	},
2644 	{ "cursor_y", FORMAT_TABLE_STRING,
2645 	  format_cb_cursor_y
2646 	},
2647 	{ "history_all_bytes", FORMAT_TABLE_STRING,
2648 	  format_cb_history_all_bytes
2649 	},
2650 	{ "history_bytes", FORMAT_TABLE_STRING,
2651 	  format_cb_history_bytes
2652 	},
2653 	{ "history_limit", FORMAT_TABLE_STRING,
2654 	  format_cb_history_limit
2655 	},
2656 	{ "history_size", FORMAT_TABLE_STRING,
2657 	  format_cb_history_size
2658 	},
2659 	{ "host", FORMAT_TABLE_STRING,
2660 	  format_cb_host
2661 	},
2662 	{ "host_short", FORMAT_TABLE_STRING,
2663 	  format_cb_host_short
2664 	},
2665 	{ "insert_flag", FORMAT_TABLE_STRING,
2666 	  format_cb_insert_flag
2667 	},
2668 	{ "keypad_cursor_flag", FORMAT_TABLE_STRING,
2669 	  format_cb_keypad_cursor_flag
2670 	},
2671 	{ "keypad_flag", FORMAT_TABLE_STRING,
2672 	  format_cb_keypad_flag
2673 	},
2674 	{ "last_window_index", FORMAT_TABLE_STRING,
2675 	  format_cb_last_window_index
2676 	},
2677 	{ "mouse_all_flag", FORMAT_TABLE_STRING,
2678 	  format_cb_mouse_all_flag
2679 	},
2680 	{ "mouse_any_flag", FORMAT_TABLE_STRING,
2681 	  format_cb_mouse_any_flag
2682 	},
2683 	{ "mouse_button_flag", FORMAT_TABLE_STRING,
2684 	  format_cb_mouse_button_flag
2685 	},
2686 	{ "mouse_line", FORMAT_TABLE_STRING,
2687 	  format_cb_mouse_line
2688 	},
2689 	{ "mouse_pane", FORMAT_TABLE_STRING,
2690 	  format_cb_mouse_pane
2691 	},
2692 	{ "mouse_sgr_flag", FORMAT_TABLE_STRING,
2693 	  format_cb_mouse_sgr_flag
2694 	},
2695 	{ "mouse_standard_flag", FORMAT_TABLE_STRING,
2696 	  format_cb_mouse_standard_flag
2697 	},
2698 	{ "mouse_utf8_flag", FORMAT_TABLE_STRING,
2699 	  format_cb_mouse_utf8_flag
2700 	},
2701 	{ "mouse_word", FORMAT_TABLE_STRING,
2702 	  format_cb_mouse_word
2703 	},
2704 	{ "mouse_x", FORMAT_TABLE_STRING,
2705 	  format_cb_mouse_x
2706 	},
2707 	{ "mouse_y", FORMAT_TABLE_STRING,
2708 	  format_cb_mouse_y
2709 	},
2710 	{ "origin_flag", FORMAT_TABLE_STRING,
2711 	  format_cb_origin_flag
2712 	},
2713 	{ "pane_active", FORMAT_TABLE_STRING,
2714 	  format_cb_pane_active
2715 	},
2716 	{ "pane_at_bottom", FORMAT_TABLE_STRING,
2717 	  format_cb_pane_at_bottom
2718 	},
2719 	{ "pane_at_left", FORMAT_TABLE_STRING,
2720 	  format_cb_pane_at_left
2721 	},
2722 	{ "pane_at_right", FORMAT_TABLE_STRING,
2723 	  format_cb_pane_at_right
2724 	},
2725 	{ "pane_at_top", FORMAT_TABLE_STRING,
2726 	  format_cb_pane_at_top
2727 	},
2728 	{ "pane_bg", FORMAT_TABLE_STRING,
2729 	  format_cb_pane_bg
2730 	},
2731 	{ "pane_bottom", FORMAT_TABLE_STRING,
2732 	  format_cb_pane_bottom
2733 	},
2734 	{ "pane_current_command", FORMAT_TABLE_STRING,
2735 	  format_cb_current_command
2736 	},
2737 	{ "pane_current_path", FORMAT_TABLE_STRING,
2738 	  format_cb_current_path
2739 	},
2740 	{ "pane_dead", FORMAT_TABLE_STRING,
2741 	  format_cb_pane_dead
2742 	},
2743 	{ "pane_dead_status", FORMAT_TABLE_STRING,
2744 	  format_cb_pane_dead_status
2745 	},
2746 	{ "pane_fg", FORMAT_TABLE_STRING,
2747 	  format_cb_pane_fg
2748 	},
2749 	{ "pane_format", FORMAT_TABLE_STRING,
2750 	  format_cb_pane_format
2751 	},
2752 	{ "pane_height", FORMAT_TABLE_STRING,
2753 	  format_cb_pane_height
2754 	},
2755 	{ "pane_id", FORMAT_TABLE_STRING,
2756 	  format_cb_pane_id
2757 	},
2758 	{ "pane_in_mode", FORMAT_TABLE_STRING,
2759 	  format_cb_pane_in_mode
2760 	},
2761 	{ "pane_index", FORMAT_TABLE_STRING,
2762 	  format_cb_pane_index
2763 	},
2764 	{ "pane_input_off", FORMAT_TABLE_STRING,
2765 	  format_cb_pane_input_off
2766 	},
2767 	{ "pane_last", FORMAT_TABLE_STRING,
2768 	  format_cb_pane_last
2769 	},
2770 	{ "pane_left", FORMAT_TABLE_STRING,
2771 	  format_cb_pane_left
2772 	},
2773 	{ "pane_marked", FORMAT_TABLE_STRING,
2774 	  format_cb_pane_marked
2775 	},
2776 	{ "pane_marked_set", FORMAT_TABLE_STRING,
2777 	  format_cb_pane_marked_set
2778 	},
2779 	{ "pane_mode", FORMAT_TABLE_STRING,
2780 	  format_cb_pane_mode
2781 	},
2782 	{ "pane_path", FORMAT_TABLE_STRING,
2783 	  format_cb_pane_path
2784 	},
2785 	{ "pane_pid", FORMAT_TABLE_STRING,
2786 	  format_cb_pane_pid
2787 	},
2788 	{ "pane_pipe", FORMAT_TABLE_STRING,
2789 	  format_cb_pane_pipe
2790 	},
2791 	{ "pane_right", FORMAT_TABLE_STRING,
2792 	  format_cb_pane_right
2793 	},
2794 	{ "pane_search_string", FORMAT_TABLE_STRING,
2795 	  format_cb_pane_search_string
2796 	},
2797 	{ "pane_start_command", FORMAT_TABLE_STRING,
2798 	  format_cb_start_command
2799 	},
2800 	{ "pane_synchronized", FORMAT_TABLE_STRING,
2801 	  format_cb_pane_synchronized
2802 	},
2803 	{ "pane_tabs", FORMAT_TABLE_STRING,
2804 	  format_cb_pane_tabs
2805 	},
2806 	{ "pane_title", FORMAT_TABLE_STRING,
2807 	  format_cb_pane_title
2808 	},
2809 	{ "pane_top", FORMAT_TABLE_STRING,
2810 	  format_cb_pane_top
2811 	},
2812 	{ "pane_tty", FORMAT_TABLE_STRING,
2813 	  format_cb_pane_tty
2814 	},
2815 	{ "pane_width", FORMAT_TABLE_STRING,
2816 	  format_cb_pane_width
2817 	},
2818 	{ "pid", FORMAT_TABLE_STRING,
2819 	  format_cb_pid
2820 	},
2821 	{ "scroll_region_lower", FORMAT_TABLE_STRING,
2822 	  format_cb_scroll_region_lower
2823 	},
2824 	{ "scroll_region_upper", FORMAT_TABLE_STRING,
2825 	  format_cb_scroll_region_upper
2826 	},
2827 	{ "session_activity", FORMAT_TABLE_TIME,
2828 	  format_cb_session_activity
2829 	},
2830 	{ "session_alerts", FORMAT_TABLE_STRING,
2831 	  format_cb_session_alerts
2832 	},
2833 	{ "session_attached", FORMAT_TABLE_STRING,
2834 	  format_cb_session_attached
2835 	},
2836 	{ "session_attached_list", FORMAT_TABLE_STRING,
2837 	  format_cb_session_attached_list
2838 	},
2839 	{ "session_created", FORMAT_TABLE_TIME,
2840 	  format_cb_session_created
2841 	},
2842 	{ "session_format", FORMAT_TABLE_STRING,
2843 	  format_cb_session_format
2844 	},
2845 	{ "session_group", FORMAT_TABLE_STRING,
2846 	  format_cb_session_group
2847 	},
2848 	{ "session_group_attached", FORMAT_TABLE_STRING,
2849 	  format_cb_session_group_attached
2850 	},
2851 	{ "session_group_attached_list", FORMAT_TABLE_STRING,
2852 	  format_cb_session_group_attached_list
2853 	},
2854 	{ "session_group_list", FORMAT_TABLE_STRING,
2855 	  format_cb_session_group_list
2856 	},
2857 	{ "session_group_many_attached", FORMAT_TABLE_STRING,
2858 	  format_cb_session_group_many_attached
2859 	},
2860 	{ "session_group_size", FORMAT_TABLE_STRING,
2861 	  format_cb_session_group_size
2862 	},
2863 	{ "session_grouped", FORMAT_TABLE_STRING,
2864 	  format_cb_session_grouped
2865 	},
2866 	{ "session_id", FORMAT_TABLE_STRING,
2867 	  format_cb_session_id
2868 	},
2869 	{ "session_last_attached", FORMAT_TABLE_TIME,
2870 	  format_cb_session_last_attached
2871 	},
2872 	{ "session_many_attached", FORMAT_TABLE_STRING,
2873 	  format_cb_session_many_attached
2874 	},
2875 	{ "session_marked", FORMAT_TABLE_STRING,
2876 	  format_cb_session_marked,
2877 	},
2878 	{ "session_name", FORMAT_TABLE_STRING,
2879 	  format_cb_session_name
2880 	},
2881 	{ "session_path", FORMAT_TABLE_STRING,
2882 	  format_cb_session_path
2883 	},
2884 	{ "session_stack", FORMAT_TABLE_STRING,
2885 	  format_cb_session_stack
2886 	},
2887 	{ "session_windows", FORMAT_TABLE_STRING,
2888 	  format_cb_session_windows
2889 	},
2890 	{ "socket_path", FORMAT_TABLE_STRING,
2891 	  format_cb_socket_path
2892 	},
2893 	{ "start_time", FORMAT_TABLE_TIME,
2894 	  format_cb_start_time
2895 	},
2896 	{ "tree_mode_format", FORMAT_TABLE_STRING,
2897 	  format_cb_tree_mode_format
2898 	},
2899 	{ "version", FORMAT_TABLE_STRING,
2900 	  format_cb_version
2901 	},
2902 	{ "window_active", FORMAT_TABLE_STRING,
2903 	  format_cb_window_active
2904 	},
2905 	{ "window_active_clients", FORMAT_TABLE_STRING,
2906 	  format_cb_window_active_clients
2907 	},
2908 	{ "window_active_clients_list", FORMAT_TABLE_STRING,
2909 	  format_cb_window_active_clients_list
2910 	},
2911 	{ "window_active_sessions", FORMAT_TABLE_STRING,
2912 	  format_cb_window_active_sessions
2913 	},
2914 	{ "window_active_sessions_list", FORMAT_TABLE_STRING,
2915 	  format_cb_window_active_sessions_list
2916 	},
2917 	{ "window_activity", FORMAT_TABLE_TIME,
2918 	  format_cb_window_activity
2919 	},
2920 	{ "window_activity_flag", FORMAT_TABLE_STRING,
2921 	  format_cb_window_activity_flag
2922 	},
2923 	{ "window_bell_flag", FORMAT_TABLE_STRING,
2924 	  format_cb_window_bell_flag
2925 	},
2926 	{ "window_bigger", FORMAT_TABLE_STRING,
2927 	  format_cb_window_bigger
2928 	},
2929 	{ "window_cell_height", FORMAT_TABLE_STRING,
2930 	  format_cb_window_cell_height
2931 	},
2932 	{ "window_cell_width", FORMAT_TABLE_STRING,
2933 	  format_cb_window_cell_width
2934 	},
2935 	{ "window_end_flag", FORMAT_TABLE_STRING,
2936 	  format_cb_window_end_flag
2937 	},
2938 	{ "window_flags", FORMAT_TABLE_STRING,
2939 	  format_cb_window_flags
2940 	},
2941 	{ "window_format", FORMAT_TABLE_STRING,
2942 	  format_cb_window_format
2943 	},
2944 	{ "window_height", FORMAT_TABLE_STRING,
2945 	  format_cb_window_height
2946 	},
2947 	{ "window_id", FORMAT_TABLE_STRING,
2948 	  format_cb_window_id
2949 	},
2950 	{ "window_index", FORMAT_TABLE_STRING,
2951 	  format_cb_window_index
2952 	},
2953 	{ "window_last_flag", FORMAT_TABLE_STRING,
2954 	  format_cb_window_last_flag
2955 	},
2956 	{ "window_layout", FORMAT_TABLE_STRING,
2957 	  format_cb_window_layout
2958 	},
2959 	{ "window_linked", FORMAT_TABLE_STRING,
2960 	  format_cb_window_linked
2961 	},
2962 	{ "window_linked_sessions", FORMAT_TABLE_STRING,
2963 	  format_cb_window_linked_sessions
2964 	},
2965 	{ "window_linked_sessions_list", FORMAT_TABLE_STRING,
2966 	  format_cb_window_linked_sessions_list
2967 	},
2968 	{ "window_marked_flag", FORMAT_TABLE_STRING,
2969 	  format_cb_window_marked_flag
2970 	},
2971 	{ "window_name", FORMAT_TABLE_STRING,
2972 	  format_cb_window_name
2973 	},
2974 	{ "window_offset_x", FORMAT_TABLE_STRING,
2975 	  format_cb_window_offset_x
2976 	},
2977 	{ "window_offset_y", FORMAT_TABLE_STRING,
2978 	  format_cb_window_offset_y
2979 	},
2980 	{ "window_panes", FORMAT_TABLE_STRING,
2981 	  format_cb_window_panes
2982 	},
2983 	{ "window_raw_flags", FORMAT_TABLE_STRING,
2984 	  format_cb_window_raw_flags
2985 	},
2986 	{ "window_silence_flag", FORMAT_TABLE_STRING,
2987 	  format_cb_window_silence_flag
2988 	},
2989 	{ "window_stack_index", FORMAT_TABLE_STRING,
2990 	  format_cb_window_stack_index
2991 	},
2992 	{ "window_start_flag", FORMAT_TABLE_STRING,
2993 	  format_cb_window_start_flag
2994 	},
2995 	{ "window_visible_layout", FORMAT_TABLE_STRING,
2996 	  format_cb_window_visible_layout
2997 	},
2998 	{ "window_width", FORMAT_TABLE_STRING,
2999 	  format_cb_window_width
3000 	},
3001 	{ "window_zoomed_flag", FORMAT_TABLE_STRING,
3002 	  format_cb_window_zoomed_flag
3003 	},
3004 	{ "wrap_flag", FORMAT_TABLE_STRING,
3005 	  format_cb_wrap_flag
3006 	}
3007 };
3008 
3009 /* Compare format table entries. */
3010 static int
3011 format_table_compare(const void *key0, const void *entry0)
3012 {
3013 	const char			*key = key0;
3014 	const struct format_table_entry	*entry = entry0;
3015 
3016 	return (strcmp(key, entry->key));
3017 }
3018 
3019 /* Get a format callback. */
3020 static struct format_table_entry *
3021 format_table_get(const char *key)
3022 {
3023 	return (bsearch(key, format_table, nitems(format_table),
3024 	    sizeof *format_table, format_table_compare));
3025 }
3026 
3027 /* Merge one format tree into another. */
3028 void
3029 format_merge(struct format_tree *ft, struct format_tree *from)
3030 {
3031 	struct format_entry	*fe;
3032 
3033 	RB_FOREACH(fe, format_entry_tree, &from->tree) {
3034 		if (fe->value != NULL)
3035 			format_add(ft, fe->key, "%s", fe->value);
3036 	}
3037 }
3038 
3039 /* Get format pane. */
3040 struct window_pane *
3041 format_get_pane(struct format_tree *ft)
3042 {
3043 	return (ft->wp);
3044 }
3045 
3046 /* Add item bits to tree. */
3047 static void
3048 format_create_add_item(struct format_tree *ft, struct cmdq_item *item)
3049 {
3050 	struct key_event	*event = cmdq_get_event(item);
3051 	struct mouse_event	*m = &event->m;
3052 
3053 	cmdq_merge_formats(item, ft);
3054 	memcpy(&ft->m, m, sizeof ft->m);
3055 }
3056 
3057 /* Create a new tree. */
3058 struct format_tree *
3059 format_create(struct client *c, struct cmdq_item *item, int tag, int flags)
3060 {
3061 	struct format_tree	*ft;
3062 
3063 	ft = xcalloc(1, sizeof *ft);
3064 	RB_INIT(&ft->tree);
3065 
3066 	if (c != NULL) {
3067 		ft->client = c;
3068 		ft->client->references++;
3069 	}
3070 	ft->item = item;
3071 
3072 	ft->tag = tag;
3073 	ft->flags = flags;
3074 
3075 	if (item != NULL)
3076 		format_create_add_item(ft, item);
3077 
3078 	return (ft);
3079 }
3080 
3081 /* Free a tree. */
3082 void
3083 format_free(struct format_tree *ft)
3084 {
3085 	struct format_entry	*fe, *fe1;
3086 
3087 	RB_FOREACH_SAFE(fe, format_entry_tree, &ft->tree, fe1) {
3088 		RB_REMOVE(format_entry_tree, &ft->tree, fe);
3089 		free(fe->value);
3090 		free(fe->key);
3091 		free(fe);
3092 	}
3093 
3094 	if (ft->client != NULL)
3095 		server_client_unref(ft->client);
3096 	free(ft);
3097 }
3098 
3099 /* Log each format. */
3100 static void
3101 format_log_debug_cb(const char *key, const char *value, void *arg)
3102 {
3103 	const char	*prefix = arg;
3104 
3105 	log_debug("%s: %s=%s", prefix, key, value);
3106 }
3107 
3108 /* Log a format tree. */
3109 void
3110 format_log_debug(struct format_tree *ft, const char *prefix)
3111 {
3112 	format_each(ft, format_log_debug_cb, (void *)prefix);
3113 }
3114 
3115 /* Walk each format. */
3116 void
3117 format_each(struct format_tree *ft, void (*cb)(const char *, const char *,
3118     void *), void *arg)
3119 {
3120 	const struct format_table_entry	*fte;
3121 	struct format_entry		*fe;
3122 	u_int				 i;
3123 	char				 s[64];
3124 	void				*value;
3125 	struct timeval			*tv;
3126 
3127 	for (i = 0; i < nitems(format_table); i++) {
3128 		fte = &format_table[i];
3129 
3130 		value = fte->cb(ft);
3131 		if (value == NULL)
3132 			continue;
3133 		if (fte->type == FORMAT_TABLE_TIME) {
3134 			tv = value;
3135 			xsnprintf(s, sizeof s, "%lld", (long long)tv->tv_sec);
3136 			cb(fte->key, s, arg);
3137 		} else {
3138 			cb(fte->key, value, arg);
3139 			free(value);
3140 		}
3141 	}
3142 	RB_FOREACH(fe, format_entry_tree, &ft->tree) {
3143 		if (fe->time != 0) {
3144 			xsnprintf(s, sizeof s, "%lld", (long long)fe->time);
3145 			cb(fe->key, s, arg);
3146 		} else {
3147 			if (fe->value == NULL && fe->cb != NULL) {
3148 				fe->value = fe->cb(ft);
3149 				if (fe->value == NULL)
3150 					fe->value = xstrdup("");
3151 			}
3152 			cb(fe->key, fe->value, arg);
3153 		}
3154 	}
3155 }
3156 
3157 /* Add a key-value pair. */
3158 void
3159 format_add(struct format_tree *ft, const char *key, const char *fmt, ...)
3160 {
3161 	struct format_entry	*fe;
3162 	struct format_entry	*fe_now;
3163 	va_list			 ap;
3164 
3165 	fe = xmalloc(sizeof *fe);
3166 	fe->key = xstrdup(key);
3167 
3168 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
3169 	if (fe_now != NULL) {
3170 		free(fe->key);
3171 		free(fe);
3172 		free(fe_now->value);
3173 		fe = fe_now;
3174 	}
3175 
3176 	fe->cb = NULL;
3177 	fe->time = 0;
3178 
3179 	va_start(ap, fmt);
3180 	xvasprintf(&fe->value, fmt, ap);
3181 	va_end(ap);
3182 }
3183 
3184 /* Add a key and time. */
3185 void
3186 format_add_tv(struct format_tree *ft, const char *key, struct timeval *tv)
3187 {
3188 	struct format_entry	*fe, *fe_now;
3189 
3190 	fe = xmalloc(sizeof *fe);
3191 	fe->key = xstrdup(key);
3192 
3193 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
3194 	if (fe_now != NULL) {
3195 		free(fe->key);
3196 		free(fe);
3197 		free(fe_now->value);
3198 		fe = fe_now;
3199 	}
3200 
3201 	fe->cb = NULL;
3202 	fe->time = tv->tv_sec;
3203 
3204 	fe->value = NULL;
3205 }
3206 
3207 /* Add a key and function. */
3208 void
3209 format_add_cb(struct format_tree *ft, const char *key, format_cb cb)
3210 {
3211 	struct format_entry	*fe;
3212 	struct format_entry	*fe_now;
3213 
3214 	fe = xmalloc(sizeof *fe);
3215 	fe->key = xstrdup(key);
3216 
3217 	fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe);
3218 	if (fe_now != NULL) {
3219 		free(fe->key);
3220 		free(fe);
3221 		free(fe_now->value);
3222 		fe = fe_now;
3223 	}
3224 
3225 	fe->cb = cb;
3226 	fe->time = 0;
3227 
3228 	fe->value = NULL;
3229 }
3230 
3231 /* Quote shell special characters in string. */
3232 static char *
3233 format_quote_shell(const char *s)
3234 {
3235 	const char	*cp;
3236 	char		*out, *at;
3237 
3238 	at = out = xmalloc(strlen(s) * 2 + 1);
3239 	for (cp = s; *cp != '\0'; cp++) {
3240 		if (strchr("|&;<>()$`\\\"'*?[# =%", *cp) != NULL)
3241 			*at++ = '\\';
3242 		*at++ = *cp;
3243 	}
3244 	*at = '\0';
3245 	return (out);
3246 }
3247 
3248 /* Quote #s in string. */
3249 static char *
3250 format_quote_style(const char *s)
3251 {
3252 	const char	*cp;
3253 	char		*out, *at;
3254 
3255 	at = out = xmalloc(strlen(s) * 2 + 1);
3256 	for (cp = s; *cp != '\0'; cp++) {
3257 		if (*cp == '#')
3258 			*at++ = '#';
3259 		*at++ = *cp;
3260 	}
3261 	*at = '\0';
3262 	return (out);
3263 }
3264 
3265 /* Make a prettier time. */
3266 static char *
3267 format_pretty_time(time_t t)
3268 {
3269 	struct tm       now_tm, tm;
3270 	time_t		now, age;
3271 	char		s[6];
3272 
3273 	time(&now);
3274 	if (now < t)
3275 		now = t;
3276 	age = now - t;
3277 
3278 	localtime_r(&now, &now_tm);
3279 	localtime_r(&t, &tm);
3280 
3281 	/* Last 24 hours. */
3282 	if (age < 24 * 3600) {
3283 		strftime(s, sizeof s, "%H:%M", &tm);
3284 		return (xstrdup(s));
3285 	}
3286 
3287 	/* This month or last 28 days. */
3288 	if ((tm.tm_year == now_tm.tm_year && tm.tm_mon == now_tm.tm_mon) ||
3289 	    age < 28 * 24 * 3600) {
3290 		strftime(s, sizeof s, "%a%d", &tm);
3291 		return (xstrdup(s));
3292 	}
3293 
3294 	/* Last 12 months. */
3295 	if ((tm.tm_year == now_tm.tm_year && tm.tm_mon < now_tm.tm_mon) ||
3296 	    (tm.tm_year == now_tm.tm_year - 1 && tm.tm_mon > now_tm.tm_mon)) {
3297 		strftime(s, sizeof s, "%d%b", &tm);
3298 		return (xstrdup(s));
3299 	}
3300 
3301 	/* Older than that. */
3302 	strftime(s, sizeof s, "%h%y", &tm);
3303 	return (xstrdup(s));
3304 }
3305 
3306 /* Find a format entry. */
3307 static char *
3308 format_find(struct format_tree *ft, const char *key, int modifiers,
3309     const char *time_format)
3310 {
3311 	struct format_table_entry	*fte;
3312 	void				*value;
3313 	struct format_entry		*fe, fe_find;
3314 	struct environ_entry		*envent;
3315 	struct options_entry		*o;
3316 	int				 idx;
3317 	char				*found = NULL, *saved, s[512];
3318 	const char			*errstr;
3319 	time_t				 t = 0;
3320 	struct tm			 tm;
3321 
3322 	o = options_parse_get(global_options, key, &idx, 0);
3323 	if (o == NULL && ft->wp != NULL)
3324 		o = options_parse_get(ft->wp->options, key, &idx, 0);
3325 	if (o == NULL && ft->w != NULL)
3326 		o = options_parse_get(ft->w->options, key, &idx, 0);
3327 	if (o == NULL)
3328 		o = options_parse_get(global_w_options, key, &idx, 0);
3329 	if (o == NULL && ft->s != NULL)
3330 		o = options_parse_get(ft->s->options, key, &idx, 0);
3331 	if (o == NULL)
3332 		o = options_parse_get(global_s_options, key, &idx, 0);
3333 	if (o != NULL) {
3334 		found = options_to_string(o, idx, 1);
3335 		goto found;
3336 	}
3337 
3338 	fte = format_table_get(key);
3339 	if (fte != NULL) {
3340 		value = fte->cb(ft);
3341 		if (fte->type == FORMAT_TABLE_TIME && value != NULL)
3342 			t = ((struct timeval *)value)->tv_sec;
3343 		else
3344 			found = value;
3345 		goto found;
3346 	}
3347 	fe_find.key = (char *)key;
3348 	fe = RB_FIND(format_entry_tree, &ft->tree, &fe_find);
3349 	if (fe != NULL) {
3350 		if (fe->time != 0) {
3351 			t = fe->time;
3352 			goto found;
3353 		}
3354 		if (fe->value == NULL && fe->cb != NULL) {
3355 			fe->value = fe->cb(ft);
3356 			if (fe->value == NULL)
3357 				fe->value = xstrdup("");
3358 		}
3359 		found = xstrdup(fe->value);
3360 		goto found;
3361 	}
3362 
3363 	if (~modifiers & FORMAT_TIMESTRING) {
3364 		envent = NULL;
3365 		if (ft->s != NULL)
3366 			envent = environ_find(ft->s->environ, key);
3367 		if (envent == NULL)
3368 			envent = environ_find(global_environ, key);
3369 		if (envent != NULL && envent->value != NULL) {
3370 			found = xstrdup(envent->value);
3371 			goto found;
3372 		}
3373 	}
3374 
3375 	return (NULL);
3376 
3377 found:
3378 	if (modifiers & FORMAT_TIMESTRING) {
3379 		if (t == 0 && found != NULL) {
3380 			t = strtonum(found, 0, INT64_MAX, &errstr);
3381 			if (errstr != NULL)
3382 				t = 0;
3383 			free(found);
3384 		}
3385 		if (t == 0)
3386 			return (NULL);
3387 		if (modifiers & FORMAT_PRETTY)
3388 			found = format_pretty_time(t);
3389 		else {
3390 			if (time_format != NULL) {
3391 				localtime_r(&t, &tm);
3392 				strftime(s, sizeof s, time_format, &tm);
3393 			} else {
3394 				ctime_r(&t, s);
3395 				s[strcspn(s, "\n")] = '\0';
3396 			}
3397 			found = xstrdup(s);
3398 		}
3399 		return (found);
3400 	}
3401 
3402 	if (t != 0)
3403 		xasprintf(&found, "%lld", (long long)t);
3404 	else if (found == NULL)
3405 		return (NULL);
3406 	if (modifiers & FORMAT_BASENAME) {
3407 		saved = found;
3408 		found = xstrdup(basename(saved));
3409 		free(saved);
3410 	}
3411 	if (modifiers & FORMAT_DIRNAME) {
3412 		saved = found;
3413 		found = xstrdup(dirname(saved));
3414 		free(saved);
3415 	}
3416 	if (modifiers & FORMAT_QUOTE_SHELL) {
3417 		saved = found;
3418 		found = xstrdup(format_quote_shell(saved));
3419 		free(saved);
3420 	}
3421 	if (modifiers & FORMAT_QUOTE_STYLE) {
3422 		saved = found;
3423 		found = xstrdup(format_quote_style(saved));
3424 		free(saved);
3425 	}
3426 	return (found);
3427 }
3428 
3429 /* Remove escaped characters from string. */
3430 static char *
3431 format_strip(const char *s)
3432 {
3433 	char	*out, *cp;
3434 	int	 brackets = 0;
3435 
3436 	cp = out = xmalloc(strlen(s) + 1);
3437 	for (; *s != '\0'; s++) {
3438 		if (*s == '#' && s[1] == '{')
3439 			brackets++;
3440 		if (*s == '#' && strchr(",#{}:", s[1]) != NULL) {
3441 			if (brackets != 0)
3442 				*cp++ = *s;
3443 			continue;
3444 		}
3445 		if (*s == '}')
3446 			brackets--;
3447 		*cp++ = *s;
3448 	}
3449 	*cp = '\0';
3450 	return (out);
3451 }
3452 
3453 /* Skip until end. */
3454 const char *
3455 format_skip(const char *s, const char *end)
3456 {
3457 	int	brackets = 0;
3458 
3459 	for (; *s != '\0'; s++) {
3460 		if (*s == '#' && s[1] == '{')
3461 			brackets++;
3462 		if (*s == '#' && strchr(",#{}:", s[1]) != NULL) {
3463 			s++;
3464 			continue;
3465 		}
3466 		if (*s == '}')
3467 			brackets--;
3468 		if (strchr(end, *s) != NULL && brackets == 0)
3469 			break;
3470 	}
3471 	if (*s == '\0')
3472 		return (NULL);
3473 	return (s);
3474 }
3475 
3476 /* Return left and right alternatives separated by commas. */
3477 static int
3478 format_choose(struct format_expand_state *es, const char *s, char **left,
3479     char **right, int expand)
3480 {
3481 	const char	*cp;
3482 	char		*left0, *right0;
3483 
3484 	cp = format_skip(s, ",");
3485 	if (cp == NULL)
3486 		return (-1);
3487 	left0 = xstrndup(s, cp - s);
3488 	right0 = xstrdup(cp + 1);
3489 
3490 	if (expand) {
3491 		*left = format_expand1(es, left0);
3492 		free(left0);
3493 		*right = format_expand1(es, right0);
3494 		free(right0);
3495 	} else {
3496 		*left = left0;
3497 		*right = right0;
3498 	}
3499 	return (0);
3500 }
3501 
3502 /* Is this true? */
3503 int
3504 format_true(const char *s)
3505 {
3506 	if (s != NULL && *s != '\0' && (s[0] != '0' || s[1] != '\0'))
3507 		return (1);
3508 	return (0);
3509 }
3510 
3511 /* Check if modifier end. */
3512 static int
3513 format_is_end(char c)
3514 {
3515 	return (c == ';' || c == ':');
3516 }
3517 
3518 /* Add to modifier list. */
3519 static void
3520 format_add_modifier(struct format_modifier **list, u_int *count,
3521     const char *c, size_t n, char **argv, int argc)
3522 {
3523 	struct format_modifier *fm;
3524 
3525 	*list = xreallocarray(*list, (*count) + 1, sizeof **list);
3526 	fm = &(*list)[(*count)++];
3527 
3528 	memcpy(fm->modifier, c, n);
3529 	fm->modifier[n] = '\0';
3530 	fm->size = n;
3531 
3532 	fm->argv = argv;
3533 	fm->argc = argc;
3534 }
3535 
3536 /* Free modifier list. */
3537 static void
3538 format_free_modifiers(struct format_modifier *list, u_int count)
3539 {
3540 	u_int	i;
3541 
3542 	for (i = 0; i < count; i++)
3543 		cmd_free_argv(list[i].argc, list[i].argv);
3544 	free(list);
3545 }
3546 
3547 /* Build modifier list. */
3548 static struct format_modifier *
3549 format_build_modifiers(struct format_expand_state *es, const char **s,
3550     u_int *count)
3551 {
3552 	const char		*cp = *s, *end;
3553 	struct format_modifier	*list = NULL;
3554 	char			 c, last[] = "X;:", **argv, *value;
3555 	int			 argc;
3556 
3557 	/*
3558 	 * Modifiers are a ; separated list of the forms:
3559 	 *      l,m,C,a,b,c,d,n,t,w,q,E,T,S,W,P,<,>
3560 	 *	=a
3561 	 *	=/a
3562 	 *      =/a/
3563 	 *	s/a/b/
3564 	 *	s/a/b
3565 	 *	||,&&,!=,==,<=,>=
3566 	 */
3567 
3568 	*count = 0;
3569 
3570 	while (*cp != '\0' && *cp != ':') {
3571 		/* Skip any separator character. */
3572 		if (*cp == ';')
3573 			cp++;
3574 
3575 		/* Check single character modifiers with no arguments. */
3576 		if (strchr("labcdnwETSWP<>", cp[0]) != NULL &&
3577 		    format_is_end(cp[1])) {
3578 			format_add_modifier(&list, count, cp, 1, NULL, 0);
3579 			cp++;
3580 			continue;
3581 		}
3582 
3583 		/* Then try double character with no arguments. */
3584 		if ((memcmp("||", cp, 2) == 0 ||
3585 		    memcmp("&&", cp, 2) == 0 ||
3586 		    memcmp("!=", cp, 2) == 0 ||
3587 		    memcmp("==", cp, 2) == 0 ||
3588 		    memcmp("<=", cp, 2) == 0 ||
3589 		    memcmp(">=", cp, 2) == 0) &&
3590 		    format_is_end(cp[2])) {
3591 			format_add_modifier(&list, count, cp, 2, NULL, 0);
3592 			cp += 2;
3593 			continue;
3594 		}
3595 
3596 		/* Now try single character with arguments. */
3597 		if (strchr("mCNst=peq", cp[0]) == NULL)
3598 			break;
3599 		c = cp[0];
3600 
3601 		/* No arguments provided. */
3602 		if (format_is_end(cp[1])) {
3603 			format_add_modifier(&list, count, cp, 1, NULL, 0);
3604 			cp++;
3605 			continue;
3606 		}
3607 		argv = NULL;
3608 		argc = 0;
3609 
3610 		/* Single argument with no wrapper character. */
3611 		if (!ispunct(cp[1]) || cp[1] == '-') {
3612 			end = format_skip(cp + 1, ":;");
3613 			if (end == NULL)
3614 				break;
3615 
3616 			argv = xcalloc(1, sizeof *argv);
3617 			value = xstrndup(cp + 1, end - (cp + 1));
3618 			argv[0] = format_expand1(es, value);
3619 			free(value);
3620 			argc = 1;
3621 
3622 			format_add_modifier(&list, count, &c, 1, argv, argc);
3623 			cp = end;
3624 			continue;
3625 		}
3626 
3627 		/* Multiple arguments with a wrapper character. */
3628 		last[0] = cp[1];
3629 		cp++;
3630 		do {
3631 			if (cp[0] == last[0] && format_is_end(cp[1])) {
3632 				cp++;
3633 				break;
3634 			}
3635 			end = format_skip(cp + 1, last);
3636 			if (end == NULL)
3637 				break;
3638 			cp++;
3639 
3640 			argv = xreallocarray(argv, argc + 1, sizeof *argv);
3641 			value = xstrndup(cp, end - cp);
3642 			argv[argc++] = format_expand1(es, value);
3643 			free(value);
3644 
3645 			cp = end;
3646 		} while (!format_is_end(cp[0]));
3647 		format_add_modifier(&list, count, &c, 1, argv, argc);
3648 	}
3649 	if (*cp != ':') {
3650 		format_free_modifiers(list, *count);
3651 		*count = 0;
3652 		return (NULL);
3653 	}
3654 	*s = cp + 1;
3655 	return (list);
3656 }
3657 
3658 /* Match against an fnmatch(3) pattern or regular expression. */
3659 static char *
3660 format_match(struct format_modifier *fm, const char *pattern, const char *text)
3661 {
3662 	const char	*s = "";
3663 	regex_t		 r;
3664 	int		 flags = 0;
3665 
3666 	if (fm->argc >= 1)
3667 		s = fm->argv[0];
3668 	if (strchr(s, 'r') == NULL) {
3669 		if (strchr(s, 'i') != NULL)
3670 			flags |= FNM_CASEFOLD;
3671 		if (fnmatch(pattern, text, flags) != 0)
3672 			return (xstrdup("0"));
3673 	} else {
3674 		flags = REG_EXTENDED|REG_NOSUB;
3675 		if (strchr(s, 'i') != NULL)
3676 			flags |= REG_ICASE;
3677 		if (regcomp(&r, pattern, flags) != 0)
3678 			return (xstrdup("0"));
3679 		if (regexec(&r, text, 0, NULL, 0) != 0) {
3680 			regfree(&r);
3681 			return (xstrdup("0"));
3682 		}
3683 		regfree(&r);
3684 	}
3685 	return (xstrdup("1"));
3686 }
3687 
3688 /* Perform substitution in string. */
3689 static char *
3690 format_sub(struct format_modifier *fm, const char *text, const char *pattern,
3691     const char *with)
3692 {
3693 	char	*value;
3694 	int	 flags = REG_EXTENDED;
3695 
3696 	if (fm->argc >= 3 && strchr(fm->argv[2], 'i') != NULL)
3697 		flags |= REG_ICASE;
3698 	value = regsub(pattern, with, text, flags);
3699 	if (value == NULL)
3700 		return (xstrdup(text));
3701 	return (value);
3702 }
3703 
3704 /* Search inside pane. */
3705 static char *
3706 format_search(struct format_modifier *fm, struct window_pane *wp, const char *s)
3707 {
3708 	int	 ignore = 0, regex = 0;
3709 	char	*value;
3710 
3711 	if (fm->argc >= 1) {
3712 		if (strchr(fm->argv[0], 'i') != NULL)
3713 			ignore = 1;
3714 		if (strchr(fm->argv[0], 'r') != NULL)
3715 			regex = 1;
3716 	}
3717 	xasprintf(&value, "%u", window_pane_search(wp, s, regex, ignore));
3718 	return (value);
3719 }
3720 
3721 /* Does session name exist? */
3722 static char *
3723 format_session_name(struct format_expand_state *es, const char *fmt)
3724 {
3725 	char		*name;
3726 	struct session	*s;
3727 
3728 	name = format_expand1(es, fmt);
3729 	RB_FOREACH(s, sessions, &sessions) {
3730 		if (strcmp(s->name, name) == 0) {
3731 			free(name);
3732 			return (xstrdup("1"));
3733 		}
3734 	}
3735 	free(name);
3736 	return (xstrdup("0"));
3737 }
3738 
3739 /* Loop over sessions. */
3740 static char *
3741 format_loop_sessions(struct format_expand_state *es, const char *fmt)
3742 {
3743 	struct format_tree		*ft = es->ft;
3744 	struct client			*c = ft->client;
3745 	struct cmdq_item		*item = ft->item;
3746 	struct format_tree		*nft;
3747 	struct format_expand_state	 next;
3748 	char				*expanded, *value;
3749 	size_t				 valuelen;
3750 	struct session			*s;
3751 
3752 	value = xcalloc(1, 1);
3753 	valuelen = 1;
3754 
3755 	RB_FOREACH(s, sessions, &sessions) {
3756 		format_log(es, "session loop: $%u", s->id);
3757 		nft = format_create(c, item, FORMAT_NONE, ft->flags);
3758 		format_defaults(nft, ft->c, s, NULL, NULL);
3759 		format_copy_state(&next, es, 0);
3760 		next.ft = nft;
3761 		expanded = format_expand1(&next, fmt);
3762 		format_free(next.ft);
3763 
3764 		valuelen += strlen(expanded);
3765 		value = xrealloc(value, valuelen);
3766 
3767 		strlcat(value, expanded, valuelen);
3768 		free(expanded);
3769 	}
3770 
3771 	return (value);
3772 }
3773 
3774 /* Does window name exist? */
3775 static char *
3776 format_window_name(struct format_expand_state *es, const char *fmt)
3777 {
3778 	struct format_tree	*ft = es->ft;
3779 	char			*name;
3780 	struct winlink		*wl;
3781 
3782 	if (ft->s == NULL) {
3783 		format_log(es, "window name but no session");
3784 		return (NULL);
3785 	}
3786 
3787 	name = format_expand1(es, fmt);
3788 	RB_FOREACH(wl, winlinks, &ft->s->windows) {
3789 		if (strcmp(wl->window->name, name) == 0) {
3790 			free(name);
3791 			return (xstrdup("1"));
3792 		}
3793 	}
3794 	free(name);
3795 	return (xstrdup("0"));
3796 }
3797 
3798 /* Loop over windows. */
3799 static char *
3800 format_loop_windows(struct format_expand_state *es, const char *fmt)
3801 {
3802 	struct format_tree		*ft = es->ft;
3803 	struct client			*c = ft->client;
3804 	struct cmdq_item		*item = ft->item;
3805 	struct format_tree		*nft;
3806 	struct format_expand_state	 next;
3807 	char				*all, *active, *use, *expanded, *value;
3808 	size_t				 valuelen;
3809 	struct winlink			*wl;
3810 	struct window			*w;
3811 
3812 	if (ft->s == NULL) {
3813 		format_log(es, "window loop but no session");
3814 		return (NULL);
3815 	}
3816 
3817 	if (format_choose(es, fmt, &all, &active, 0) != 0) {
3818 		all = xstrdup(fmt);
3819 		active = NULL;
3820 	}
3821 
3822 	value = xcalloc(1, 1);
3823 	valuelen = 1;
3824 
3825 	RB_FOREACH(wl, winlinks, &ft->s->windows) {
3826 		w = wl->window;
3827 		format_log(es, "window loop: %u @%u", wl->idx, w->id);
3828 		if (active != NULL && wl == ft->s->curw)
3829 			use = active;
3830 		else
3831 			use = all;
3832 		nft = format_create(c, item, FORMAT_WINDOW|w->id, ft->flags);
3833 		format_defaults(nft, ft->c, ft->s, wl, NULL);
3834 		format_copy_state(&next, es, 0);
3835 		next.ft = nft;
3836 		expanded = format_expand1(&next, use);
3837 		format_free(nft);
3838 
3839 		valuelen += strlen(expanded);
3840 		value = xrealloc(value, valuelen);
3841 
3842 		strlcat(value, expanded, valuelen);
3843 		free(expanded);
3844 	}
3845 
3846 	free(active);
3847 	free(all);
3848 
3849 	return (value);
3850 }
3851 
3852 /* Loop over panes. */
3853 static char *
3854 format_loop_panes(struct format_expand_state *es, const char *fmt)
3855 {
3856 	struct format_tree		*ft = es->ft;
3857 	struct client			*c = ft->client;
3858 	struct cmdq_item		*item = ft->item;
3859 	struct format_tree		*nft;
3860 	struct format_expand_state	 next;
3861 	char				*all, *active, *use, *expanded, *value;
3862 	size_t				 valuelen;
3863 	struct window_pane		*wp;
3864 
3865 	if (ft->w == NULL) {
3866 		format_log(es, "pane loop but no window");
3867 		return (NULL);
3868 	}
3869 
3870 	if (format_choose(es, fmt, &all, &active, 0) != 0) {
3871 		all = xstrdup(fmt);
3872 		active = NULL;
3873 	}
3874 
3875 	value = xcalloc(1, 1);
3876 	valuelen = 1;
3877 
3878 	TAILQ_FOREACH(wp, &ft->w->panes, entry) {
3879 		format_log(es, "pane loop: %%%u", wp->id);
3880 		if (active != NULL && wp == ft->w->active)
3881 			use = active;
3882 		else
3883 			use = all;
3884 		nft = format_create(c, item, FORMAT_PANE|wp->id, ft->flags);
3885 		format_defaults(nft, ft->c, ft->s, ft->wl, wp);
3886 		format_copy_state(&next, es, 0);
3887 		next.ft = nft;
3888 		expanded = format_expand1(&next, use);
3889 		format_free(nft);
3890 
3891 		valuelen += strlen(expanded);
3892 		value = xrealloc(value, valuelen);
3893 
3894 		strlcat(value, expanded, valuelen);
3895 		free(expanded);
3896 	}
3897 
3898 	free(active);
3899 	free(all);
3900 
3901 	return (value);
3902 }
3903 
3904 static char *
3905 format_replace_expression(struct format_modifier *mexp,
3906     struct format_expand_state *es, const char *copy)
3907 {
3908 	int			 argc = mexp->argc;
3909 	const char		*errstr;
3910 	char			*endch, *value, *left = NULL, *right = NULL;
3911 	int			 use_fp = 0;
3912 	u_int			 prec = 0;
3913 	double			 mleft, mright, result;
3914 	enum { ADD,
3915 	       SUBTRACT,
3916 	       MULTIPLY,
3917 	       DIVIDE,
3918 	       MODULUS,
3919 	       EQUAL,
3920 	       NOT_EQUAL,
3921 	       GREATER_THAN,
3922 	       GREATER_THAN_EQUAL,
3923 	       LESS_THAN,
3924 	       LESS_THAN_EQUAL } operator;
3925 
3926 	if (strcmp(mexp->argv[0], "+") == 0)
3927 		operator = ADD;
3928 	else if (strcmp(mexp->argv[0], "-") == 0)
3929 		operator = SUBTRACT;
3930 	else if (strcmp(mexp->argv[0], "*") == 0)
3931 		operator = MULTIPLY;
3932 	else if (strcmp(mexp->argv[0], "/") == 0)
3933 		operator = DIVIDE;
3934 	else if (strcmp(mexp->argv[0], "%") == 0 ||
3935 	    strcmp(mexp->argv[0], "m") == 0)
3936 		operator = MODULUS;
3937 	else if (strcmp(mexp->argv[0], "==") == 0)
3938 		operator = EQUAL;
3939 	else if (strcmp(mexp->argv[0], "!=") == 0)
3940 		operator = NOT_EQUAL;
3941 	else if (strcmp(mexp->argv[0], ">") == 0)
3942 		operator = GREATER_THAN;
3943 	else if (strcmp(mexp->argv[0], "<") == 0)
3944 		operator = LESS_THAN;
3945 	else if (strcmp(mexp->argv[0], ">=") == 0)
3946 		operator = GREATER_THAN_EQUAL;
3947 	else if (strcmp(mexp->argv[0], "<=") == 0)
3948 		operator = LESS_THAN_EQUAL;
3949 	else {
3950 		format_log(es, "expression has no valid operator: '%s'",
3951 		    mexp->argv[0]);
3952 		goto fail;
3953 	}
3954 
3955 	/* The second argument may be flags. */
3956 	if (argc >= 2 && strchr(mexp->argv[1], 'f') != NULL) {
3957 		use_fp = 1;
3958 		prec = 2;
3959 	}
3960 
3961 	/* The third argument may be precision. */
3962 	if (argc >= 3) {
3963 		prec = strtonum(mexp->argv[2], INT_MIN, INT_MAX, &errstr);
3964 		if (errstr != NULL) {
3965 			format_log(es, "expression precision %s: %s", errstr,
3966 			    mexp->argv[2]);
3967 			goto fail;
3968 		}
3969 	}
3970 
3971 	if (format_choose(es, copy, &left, &right, 1) != 0) {
3972 		format_log(es, "expression syntax error");
3973 		goto fail;
3974 	}
3975 
3976 	mleft = strtod(left, &endch);
3977 	if (*endch != '\0') {
3978 		format_log(es, "expression left side is invalid: %s", left);
3979 		goto fail;
3980 	}
3981 
3982 	mright = strtod(right, &endch);
3983 	if (*endch != '\0') {
3984 		format_log(es, "expression right side is invalid: %s", right);
3985 		goto fail;
3986 	}
3987 
3988 	if (!use_fp) {
3989 		mleft = (long long)mleft;
3990 		mright = (long long)mright;
3991 	}
3992 	format_log(es, "expression left side is: %.*f", prec, mleft);
3993 	format_log(es, "expression right side is: %.*f", prec, mright);
3994 
3995 	switch (operator) {
3996 	case ADD:
3997 		result = mleft + mright;
3998 		break;
3999 	case SUBTRACT:
4000 		result = mleft - mright;
4001 		break;
4002 	case MULTIPLY:
4003 		result = mleft * mright;
4004 		break;
4005 	case DIVIDE:
4006 		result = mleft / mright;
4007 		break;
4008 	case MODULUS:
4009 		result = fmod(mleft, mright);
4010 		break;
4011 	case EQUAL:
4012 		result = fabs(mleft - mright) < 1e-9;
4013 		break;
4014 	case NOT_EQUAL:
4015 		result = fabs(mleft - mright) > 1e-9;
4016 		break;
4017 	case GREATER_THAN:
4018 		result = (mleft > mright);
4019 		break;
4020 	case GREATER_THAN_EQUAL:
4021 		result = (mleft >= mright);
4022 		break;
4023 	case LESS_THAN:
4024 		result = (mleft < mright);
4025 		break;
4026 	case LESS_THAN_EQUAL:
4027 		result = (mleft <= mright);
4028 		break;
4029 	}
4030 	if (use_fp)
4031 		xasprintf(&value, "%.*f", prec, result);
4032 	else
4033 		xasprintf(&value, "%.*f", prec, (double)(long long)result);
4034 	format_log(es, "expression result is %s", value);
4035 
4036 	free(right);
4037 	free(left);
4038 	return (value);
4039 
4040 fail:
4041 	free(right);
4042 	free(left);
4043 	return (NULL);
4044 }
4045 
4046 /* Replace a key. */
4047 static int
4048 format_replace(struct format_expand_state *es, const char *key, size_t keylen,
4049     char **buf, size_t *len, size_t *off)
4050 {
4051 	struct format_tree		 *ft = es->ft;
4052 	struct window_pane		 *wp = ft->wp;
4053 	const char			 *errstr, *copy, *cp, *marker = NULL;
4054 	const char			 *time_format = NULL;
4055 	char				 *copy0, *condition, *found, *new;
4056 	char				 *value, *left, *right;
4057 	size_t				  valuelen;
4058 	int				  modifiers = 0, limit = 0, width = 0;
4059 	int				  j, c;
4060 	struct format_modifier		 *list, *cmp = NULL, *search = NULL;
4061 	struct format_modifier		**sub = NULL, *mexp = NULL, *fm;
4062 	u_int				  i, count, nsub = 0;
4063 	struct format_expand_state	  next;
4064 
4065 	/* Make a copy of the key. */
4066 	copy = copy0 = xstrndup(key, keylen);
4067 
4068 	/* Process modifier list. */
4069 	list = format_build_modifiers(es, &copy, &count);
4070 	for (i = 0; i < count; i++) {
4071 		fm = &list[i];
4072 		if (format_logging(ft)) {
4073 			format_log(es, "modifier %u is %s", i, fm->modifier);
4074 			for (j = 0; j < fm->argc; j++) {
4075 				format_log(es, "modifier %u argument %d: %s", i,
4076 				    j, fm->argv[j]);
4077 			}
4078 		}
4079 		if (fm->size == 1) {
4080 			switch (fm->modifier[0]) {
4081 			case 'm':
4082 			case '<':
4083 			case '>':
4084 				cmp = fm;
4085 				break;
4086 			case 'C':
4087 				search = fm;
4088 				break;
4089 			case 's':
4090 				if (fm->argc < 2)
4091 					break;
4092 				sub = xreallocarray(sub, nsub + 1, sizeof *sub);
4093 				sub[nsub++] = fm;
4094 				break;
4095 			case '=':
4096 				if (fm->argc < 1)
4097 					break;
4098 				limit = strtonum(fm->argv[0], INT_MIN, INT_MAX,
4099 				    &errstr);
4100 				if (errstr != NULL)
4101 					limit = 0;
4102 				if (fm->argc >= 2 && fm->argv[1] != NULL)
4103 					marker = fm->argv[1];
4104 				break;
4105 			case 'p':
4106 				if (fm->argc < 1)
4107 					break;
4108 				width = strtonum(fm->argv[0], INT_MIN, INT_MAX,
4109 				    &errstr);
4110 				if (errstr != NULL)
4111 					width = 0;
4112 				break;
4113 			case 'w':
4114 				modifiers |= FORMAT_WIDTH;
4115 				break;
4116 			case 'e':
4117 				if (fm->argc < 1 || fm->argc > 3)
4118 					break;
4119 				mexp = fm;
4120 				break;
4121 			case 'l':
4122 				modifiers |= FORMAT_LITERAL;
4123 				break;
4124 			case 'a':
4125 				modifiers |= FORMAT_CHARACTER;
4126 				break;
4127 			case 'b':
4128 				modifiers |= FORMAT_BASENAME;
4129 				break;
4130 			case 'c':
4131 				modifiers |= FORMAT_COLOUR;
4132 				break;
4133 			case 'd':
4134 				modifiers |= FORMAT_DIRNAME;
4135 				break;
4136 			case 'n':
4137 				modifiers |= FORMAT_LENGTH;
4138 				break;
4139 			case 't':
4140 				modifiers |= FORMAT_TIMESTRING;
4141 				if (fm->argc < 1)
4142 					break;
4143 				if (strchr(fm->argv[0], 'p') != NULL)
4144 					modifiers |= FORMAT_PRETTY;
4145 				else if (fm->argc >= 2 &&
4146 				    strchr(fm->argv[0], 'f') != NULL)
4147 					time_format = format_strip(fm->argv[1]);
4148 				break;
4149 			case 'q':
4150 				if (fm->argc < 1)
4151 					modifiers |= FORMAT_QUOTE_SHELL;
4152 				else if (strchr(fm->argv[0], 'e') != NULL ||
4153 				    strchr(fm->argv[0], 'h') != NULL)
4154 					modifiers |= FORMAT_QUOTE_STYLE;
4155 				break;
4156 			case 'E':
4157 				modifiers |= FORMAT_EXPAND;
4158 				break;
4159 			case 'T':
4160 				modifiers |= FORMAT_EXPANDTIME;
4161 				break;
4162 			case 'N':
4163 				if (fm->argc < 1 ||
4164 				    strchr(fm->argv[0], 'w') != NULL)
4165 					modifiers |= FORMAT_WINDOW_NAME;
4166 				else if (strchr(fm->argv[0], 's') != NULL)
4167 					modifiers |= FORMAT_SESSION_NAME;
4168 				break;
4169 			case 'S':
4170 				modifiers |= FORMAT_SESSIONS;
4171 				break;
4172 			case 'W':
4173 				modifiers |= FORMAT_WINDOWS;
4174 				break;
4175 			case 'P':
4176 				modifiers |= FORMAT_PANES;
4177 				break;
4178 			}
4179 		} else if (fm->size == 2) {
4180 			if (strcmp(fm->modifier, "||") == 0 ||
4181 			    strcmp(fm->modifier, "&&") == 0 ||
4182 			    strcmp(fm->modifier, "==") == 0 ||
4183 			    strcmp(fm->modifier, "!=") == 0 ||
4184 			    strcmp(fm->modifier, ">=") == 0 ||
4185 			    strcmp(fm->modifier, "<=") == 0)
4186 				cmp = fm;
4187 		}
4188 	}
4189 
4190 	/* Is this a literal string? */
4191 	if (modifiers & FORMAT_LITERAL) {
4192 		value = xstrdup(copy);
4193 		goto done;
4194 	}
4195 
4196 	/* Is this a character? */
4197 	if (modifiers & FORMAT_CHARACTER) {
4198 		new = format_expand1(es, copy);
4199 		c = strtonum(new, 32, 126, &errstr);
4200 		if (errstr != NULL)
4201 			value = xstrdup("");
4202 		else
4203 			xasprintf(&value, "%c", c);
4204 		free(new);
4205 		goto done;
4206 	}
4207 
4208 	/* Is this a colour? */
4209 	if (modifiers & FORMAT_COLOUR) {
4210 		new = format_expand1(es, copy);
4211 		c = colour_fromstring(new);
4212 		if (c == -1 || (c = colour_force_rgb(c)) == -1)
4213 			value = xstrdup("");
4214 		else
4215 			xasprintf(&value, "%06x", c & 0xffffff);
4216 		free(new);
4217 		goto done;
4218 	}
4219 
4220 	/* Is this a loop, comparison or condition? */
4221 	if (modifiers & FORMAT_SESSIONS) {
4222 		value = format_loop_sessions(es, copy);
4223 		if (value == NULL)
4224 			goto fail;
4225 	} else if (modifiers & FORMAT_WINDOWS) {
4226 		value = format_loop_windows(es, copy);
4227 		if (value == NULL)
4228 			goto fail;
4229 	} else if (modifiers & FORMAT_PANES) {
4230 		value = format_loop_panes(es, copy);
4231 		if (value == NULL)
4232 			goto fail;
4233 	} else if (modifiers & FORMAT_WINDOW_NAME) {
4234 		value = format_window_name(es, copy);
4235 		if (value == NULL)
4236 			goto fail;
4237 	} else if (modifiers & FORMAT_SESSION_NAME) {
4238 		value = format_session_name(es, copy);
4239 		if (value == NULL)
4240 			goto fail;
4241 	} else if (search != NULL) {
4242 		/* Search in pane. */
4243 		new = format_expand1(es, copy);
4244 		if (wp == NULL) {
4245 			format_log(es, "search '%s' but no pane", new);
4246 			value = xstrdup("0");
4247 		} else {
4248 			format_log(es, "search '%s' pane %%%u", new, wp->id);
4249 			value = format_search(search, wp, new);
4250 		}
4251 		free(new);
4252 	} else if (cmp != NULL) {
4253 		/* Comparison of left and right. */
4254 		if (format_choose(es, copy, &left, &right, 1) != 0) {
4255 			format_log(es, "compare %s syntax error: %s",
4256 			    cmp->modifier, copy);
4257 			goto fail;
4258 		}
4259 		format_log(es, "compare %s left is: %s", cmp->modifier, left);
4260 		format_log(es, "compare %s right is: %s", cmp->modifier, right);
4261 
4262 		if (strcmp(cmp->modifier, "||") == 0) {
4263 			if (format_true(left) || format_true(right))
4264 				value = xstrdup("1");
4265 			else
4266 				value = xstrdup("0");
4267 		} else if (strcmp(cmp->modifier, "&&") == 0) {
4268 			if (format_true(left) && format_true(right))
4269 				value = xstrdup("1");
4270 			else
4271 				value = xstrdup("0");
4272 		} else if (strcmp(cmp->modifier, "==") == 0) {
4273 			if (strcmp(left, right) == 0)
4274 				value = xstrdup("1");
4275 			else
4276 				value = xstrdup("0");
4277 		} else if (strcmp(cmp->modifier, "!=") == 0) {
4278 			if (strcmp(left, right) != 0)
4279 				value = xstrdup("1");
4280 			else
4281 				value = xstrdup("0");
4282 		} else if (strcmp(cmp->modifier, "<") == 0) {
4283 			if (strcmp(left, right) < 0)
4284 				value = xstrdup("1");
4285 			else
4286 				value = xstrdup("0");
4287 		} else if (strcmp(cmp->modifier, ">") == 0) {
4288 			if (strcmp(left, right) > 0)
4289 				value = xstrdup("1");
4290 			else
4291 				value = xstrdup("0");
4292 		} else if (strcmp(cmp->modifier, "<=") == 0) {
4293 			if (strcmp(left, right) <= 0)
4294 				value = xstrdup("1");
4295 			else
4296 				value = xstrdup("0");
4297 		} else if (strcmp(cmp->modifier, ">=") == 0) {
4298 			if (strcmp(left, right) >= 0)
4299 				value = xstrdup("1");
4300 			else
4301 				value = xstrdup("0");
4302 		} else if (strcmp(cmp->modifier, "m") == 0)
4303 			value = format_match(cmp, left, right);
4304 
4305 		free(right);
4306 		free(left);
4307 	} else if (*copy == '?') {
4308 		/* Conditional: check first and choose second or third. */
4309 		cp = format_skip(copy + 1, ",");
4310 		if (cp == NULL) {
4311 			format_log(es, "condition syntax error: %s", copy + 1);
4312 			goto fail;
4313 		}
4314 		condition = xstrndup(copy + 1, cp - (copy + 1));
4315 		format_log(es, "condition is: %s", condition);
4316 
4317 		found = format_find(ft, condition, modifiers, time_format);
4318 		if (found == NULL) {
4319 			/*
4320 			 * If the condition not found, try to expand it. If
4321 			 * the expansion doesn't have any effect, then assume
4322 			 * false.
4323 			 */
4324 			found = format_expand1(es, condition);
4325 			if (strcmp(found, condition) == 0) {
4326 				free(found);
4327 				found = xstrdup("");
4328 				format_log(es,
4329 				    "condition '%s' not found; assuming false",
4330 				    condition);
4331 			}
4332 		} else {
4333 			format_log(es, "condition '%s' found: %s", condition,
4334 			    found);
4335 		}
4336 
4337 		if (format_choose(es, cp + 1, &left, &right, 0) != 0) {
4338 			format_log(es, "condition '%s' syntax error: %s",
4339 			    condition, cp + 1);
4340 			free(found);
4341 			goto fail;
4342 		}
4343 		if (format_true(found)) {
4344 			format_log(es, "condition '%s' is true", condition);
4345 			value = format_expand1(es, left);
4346 		} else {
4347 			format_log(es, "condition '%s' is false", condition);
4348 			value = format_expand1(es, right);
4349 		}
4350 		free(right);
4351 		free(left);
4352 
4353 		free(condition);
4354 		free(found);
4355 	} else if (mexp != NULL) {
4356 		value = format_replace_expression(mexp, es, copy);
4357 		if (value == NULL)
4358 			value = xstrdup("");
4359 	} else {
4360 		if (strstr(copy, "#{") != 0) {
4361 			format_log(es, "expanding inner format '%s'", copy);
4362 			value = format_expand1(es, copy);
4363 		} else {
4364 			value = format_find(ft, copy, modifiers, time_format);
4365 			if (value == NULL) {
4366 				format_log(es, "format '%s' not found", copy);
4367 				value = xstrdup("");
4368 			} else {
4369 				format_log(es, "format '%s' found: %s", copy,
4370 				    value);
4371 			}
4372 		}
4373 	}
4374 
4375 done:
4376 	/* Expand again if required. */
4377 	if (modifiers & FORMAT_EXPAND) {
4378 		new = format_expand1(es, value);
4379 		free(value);
4380 		value = new;
4381 	} else if (modifiers & FORMAT_EXPANDTIME) {
4382 		format_copy_state(&next, es, FORMAT_EXPAND_TIME);
4383 		new = format_expand1(&next, value);
4384 		free(value);
4385 		value = new;
4386 	}
4387 
4388 	/* Perform substitution if any. */
4389 	for (i = 0; i < nsub; i++) {
4390 		left = format_expand1(es, sub[i]->argv[0]);
4391 		right = format_expand1(es, sub[i]->argv[1]);
4392 		new = format_sub(sub[i], value, left, right);
4393 		format_log(es, "substitute '%s' to '%s': %s", left, right, new);
4394 		free(value);
4395 		value = new;
4396 		free(right);
4397 		free(left);
4398 	}
4399 
4400 	/* Truncate the value if needed. */
4401 	if (limit > 0) {
4402 		new = format_trim_left(value, limit);
4403 		if (marker != NULL && strcmp(new, value) != 0) {
4404 			free(value);
4405 			xasprintf(&value, "%s%s", new, marker);
4406 		} else {
4407 			free(value);
4408 			value = new;
4409 		}
4410 		format_log(es, "applied length limit %d: %s", limit, value);
4411 	} else if (limit < 0) {
4412 		new = format_trim_right(value, -limit);
4413 		if (marker != NULL && strcmp(new, value) != 0) {
4414 			free(value);
4415 			xasprintf(&value, "%s%s", marker, new);
4416 		} else {
4417 			free(value);
4418 			value = new;
4419 		}
4420 		format_log(es, "applied length limit %d: %s", limit, value);
4421 	}
4422 
4423 	/* Pad the value if needed. */
4424 	if (width > 0) {
4425 		new = utf8_padcstr(value, width);
4426 		free(value);
4427 		value = new;
4428 		format_log(es, "applied padding width %d: %s", width, value);
4429 	} else if (width < 0) {
4430 		new = utf8_rpadcstr(value, -width);
4431 		free(value);
4432 		value = new;
4433 		format_log(es, "applied padding width %d: %s", width, value);
4434 	}
4435 
4436 	/* Replace with the length or width if needed. */
4437 	if (modifiers & FORMAT_LENGTH) {
4438 		xasprintf(&new, "%zu", strlen(value));
4439 		free(value);
4440 		value = new;
4441 		format_log(es, "replacing with length: %s", new);
4442 	}
4443 	if (modifiers & FORMAT_WIDTH) {
4444 		xasprintf(&new, "%u", format_width(value));
4445 		free(value);
4446 		value = new;
4447 		format_log(es, "replacing with width: %s", new);
4448 	}
4449 
4450 	/* Expand the buffer and copy in the value. */
4451 	valuelen = strlen(value);
4452 	while (*len - *off < valuelen + 1) {
4453 		*buf = xreallocarray(*buf, 2, *len);
4454 		*len *= 2;
4455 	}
4456 	memcpy(*buf + *off, value, valuelen);
4457 	*off += valuelen;
4458 
4459 	format_log(es, "replaced '%s' with '%s'", copy0, value);
4460 	free(value);
4461 
4462 	free(sub);
4463 	format_free_modifiers(list, count);
4464 	free(copy0);
4465 	return (0);
4466 
4467 fail:
4468 	format_log(es, "failed %s", copy0);
4469 
4470 	free(sub);
4471 	format_free_modifiers(list, count);
4472 	free(copy0);
4473 	return (-1);
4474 }
4475 
4476 /* Expand keys in a template. */
4477 static char *
4478 format_expand1(struct format_expand_state *es, const char *fmt)
4479 {
4480 	struct format_tree	*ft = es->ft;
4481 	char			*buf, *out, *name;
4482 	const char		*ptr, *s;
4483 	size_t			 off, len, n, outlen;
4484 	int     		 ch, brackets;
4485 	char			 expanded[8192];
4486 
4487 	if (fmt == NULL || *fmt == '\0')
4488 		return (xstrdup(""));
4489 
4490 	if (es->loop == FORMAT_LOOP_LIMIT) {
4491 		format_log(es, "reached loop limit (%u)", FORMAT_LOOP_LIMIT);
4492 		return (xstrdup(""));
4493 	}
4494 	es->loop++;
4495 
4496 	format_log(es, "expanding format: %s", fmt);
4497 
4498 	if ((es->flags & FORMAT_EXPAND_TIME) && strchr(fmt, '%') != NULL) {
4499 		if (es->time == 0) {
4500 			es->time = time(NULL);
4501 			localtime_r(&es->time, &es->tm);
4502 		}
4503 		if (strftime(expanded, sizeof expanded, fmt, &es->tm) == 0) {
4504 			format_log(es, "format is too long");
4505 			return (xstrdup(""));
4506 		}
4507 		if (format_logging(ft) && strcmp(expanded, fmt) != 0)
4508 			format_log(es, "after time expanded: %s", expanded);
4509 		fmt = expanded;
4510 	}
4511 
4512 	len = 64;
4513 	buf = xmalloc(len);
4514 	off = 0;
4515 
4516 	while (*fmt != '\0') {
4517 		if (*fmt != '#') {
4518 			while (len - off < 2) {
4519 				buf = xreallocarray(buf, 2, len);
4520 				len *= 2;
4521 			}
4522 			buf[off++] = *fmt++;
4523 			continue;
4524 		}
4525 		fmt++;
4526 
4527 		ch = (u_char)*fmt++;
4528 		switch (ch) {
4529 		case '(':
4530 			brackets = 1;
4531 			for (ptr = fmt; *ptr != '\0'; ptr++) {
4532 				if (*ptr == '(')
4533 					brackets++;
4534 				if (*ptr == ')' && --brackets == 0)
4535 					break;
4536 			}
4537 			if (*ptr != ')' || brackets != 0)
4538 				break;
4539 			n = ptr - fmt;
4540 
4541 			name = xstrndup(fmt, n);
4542 			format_log(es, "found #(): %s", name);
4543 
4544 			if ((ft->flags & FORMAT_NOJOBS) ||
4545 			    (es->flags & FORMAT_EXPAND_NOJOBS)) {
4546 				out = xstrdup("");
4547 				format_log(es, "#() is disabled");
4548 			} else {
4549 				out = format_job_get(es, name);
4550 				format_log(es, "#() result: %s", out);
4551 			}
4552 			free(name);
4553 
4554 			outlen = strlen(out);
4555 			while (len - off < outlen + 1) {
4556 				buf = xreallocarray(buf, 2, len);
4557 				len *= 2;
4558 			}
4559 			memcpy(buf + off, out, outlen);
4560 			off += outlen;
4561 
4562 			free(out);
4563 
4564 			fmt += n + 1;
4565 			continue;
4566 		case '{':
4567 			ptr = format_skip((char *)fmt - 2, "}");
4568 			if (ptr == NULL)
4569 				break;
4570 			n = ptr - fmt;
4571 
4572 			format_log(es, "found #{}: %.*s", (int)n, fmt);
4573 			if (format_replace(es, fmt, n, &buf, &len, &off) != 0)
4574 				break;
4575 			fmt += n + 1;
4576 			continue;
4577 		case '#':
4578 			/*
4579 			 * If ##[ (with two or more #s), then it is a style and
4580 			 * can be left for format_draw to handle.
4581 			 */
4582 			ptr = fmt;
4583 			n = 2;
4584 			while (*ptr == '#') {
4585 				ptr++;
4586 				n++;
4587 			}
4588 			if (*ptr == '[') {
4589 				format_log(es, "found #*%zu[", n);
4590 				while (len - off < n + 2) {
4591 					buf = xreallocarray(buf, 2, len);
4592 					len *= 2;
4593 				}
4594 				memcpy(buf + off, fmt - 2, n + 1);
4595 				off += n + 1;
4596 				fmt = ptr + 1;
4597 				continue;
4598 			}
4599 			/* FALLTHROUGH */
4600 		case '}':
4601 		case ',':
4602 			format_log(es, "found #%c", ch);
4603 			while (len - off < 2) {
4604 				buf = xreallocarray(buf, 2, len);
4605 				len *= 2;
4606 			}
4607 			buf[off++] = ch;
4608 			continue;
4609 		default:
4610 			s = NULL;
4611 			if (ch >= 'A' && ch <= 'Z')
4612 				s = format_upper[ch - 'A'];
4613 			else if (ch >= 'a' && ch <= 'z')
4614 				s = format_lower[ch - 'a'];
4615 			if (s == NULL) {
4616 				while (len - off < 3) {
4617 					buf = xreallocarray(buf, 2, len);
4618 					len *= 2;
4619 				}
4620 				buf[off++] = '#';
4621 				buf[off++] = ch;
4622 				continue;
4623 			}
4624 			n = strlen(s);
4625 			format_log(es, "found #%c: %s", ch, s);
4626 			if (format_replace(es, s, n, &buf, &len, &off) != 0)
4627 				break;
4628 			continue;
4629 		}
4630 
4631 		break;
4632 	}
4633 	buf[off] = '\0';
4634 
4635 	format_log(es, "result is: %s", buf);
4636 	es->loop--;
4637 
4638 	return (buf);
4639 }
4640 
4641 /* Expand keys in a template, passing through strftime first. */
4642 char *
4643 format_expand_time(struct format_tree *ft, const char *fmt)
4644 {
4645 	struct format_expand_state	es;
4646 
4647 	memset(&es, 0, sizeof es);
4648 	es.ft = ft;
4649 	es.flags = FORMAT_EXPAND_TIME;
4650 	return (format_expand1(&es, fmt));
4651 }
4652 
4653 /* Expand keys in a template. */
4654 char *
4655 format_expand(struct format_tree *ft, const char *fmt)
4656 {
4657 	struct format_expand_state	es;
4658 
4659 	memset(&es, 0, sizeof es);
4660 	es.ft = ft;
4661 	es.flags = 0;
4662 	return (format_expand1(&es, fmt));
4663 }
4664 
4665 /* Expand a single string. */
4666 char *
4667 format_single(struct cmdq_item *item, const char *fmt, struct client *c,
4668     struct session *s, struct winlink *wl, struct window_pane *wp)
4669 {
4670 	struct format_tree	*ft;
4671 	char			*expanded;
4672 
4673 	ft = format_create_defaults(item, c, s, wl, wp);
4674 	expanded = format_expand(ft, fmt);
4675 	format_free(ft);
4676 	return (expanded);
4677 }
4678 
4679 /* Expand a single string using state. */
4680 char *
4681 format_single_from_state(struct cmdq_item *item, const char *fmt,
4682     struct client *c, struct cmd_find_state *fs)
4683 {
4684 	return (format_single(item, fmt, c, fs->s, fs->wl, fs->wp));
4685 }
4686 
4687 /* Expand a single string using target. */
4688 char *
4689 format_single_from_target(struct cmdq_item *item, const char *fmt)
4690 {
4691 	struct client	*tc = cmdq_get_target_client(item);
4692 
4693 	return (format_single_from_state(item, fmt, tc, cmdq_get_target(item)));
4694 }
4695 
4696 /* Create and add defaults. */
4697 struct format_tree *
4698 format_create_defaults(struct cmdq_item *item, struct client *c,
4699     struct session *s, struct winlink *wl, struct window_pane *wp)
4700 {
4701 	struct format_tree	*ft;
4702 
4703 	if (item != NULL)
4704 		ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0);
4705 	else
4706 		ft = format_create(NULL, item, FORMAT_NONE, 0);
4707 	format_defaults(ft, c, s, wl, wp);
4708 	return (ft);
4709 }
4710 
4711 /* Create and add defaults using state. */
4712 struct format_tree *
4713 format_create_from_state(struct cmdq_item *item, struct client *c,
4714     struct cmd_find_state *fs)
4715 {
4716 	return (format_create_defaults(item, c, fs->s, fs->wl, fs->wp));
4717 }
4718 
4719 /* Create and add defaults using target. */
4720 struct format_tree *
4721 format_create_from_target(struct cmdq_item *item)
4722 {
4723 	struct client	*tc = cmdq_get_target_client(item);
4724 
4725 	return (format_create_from_state(item, tc, cmdq_get_target(item)));
4726 }
4727 
4728 /* Set defaults for any of arguments that are not NULL. */
4729 void
4730 format_defaults(struct format_tree *ft, struct client *c, struct session *s,
4731     struct winlink *wl, struct window_pane *wp)
4732 {
4733 	struct paste_buffer	*pb;
4734 
4735 	if (c != NULL && c->name != NULL)
4736 		log_debug("%s: c=%s", __func__, c->name);
4737 	else
4738 		log_debug("%s: c=none", __func__);
4739 	if (s != NULL)
4740 		log_debug("%s: s=$%u", __func__, s->id);
4741 	else
4742 		log_debug("%s: s=none", __func__);
4743 	if (wl != NULL)
4744 		log_debug("%s: wl=%u", __func__, wl->idx);
4745 	else
4746 		log_debug("%s: wl=none", __func__);
4747 	if (wp != NULL)
4748 		log_debug("%s: wp=%%%u", __func__, wp->id);
4749 	else
4750 		log_debug("%s: wp=none", __func__);
4751 
4752 	if (c != NULL && s != NULL && c->session != s)
4753 		log_debug("%s: session does not match", __func__);
4754 
4755 	if (wp != NULL)
4756 		ft->type = FORMAT_TYPE_PANE;
4757 	else if (wl != NULL)
4758 		ft->type = FORMAT_TYPE_WINDOW;
4759 	else if (s != NULL)
4760 		ft->type = FORMAT_TYPE_SESSION;
4761 	else
4762 		ft->type = FORMAT_TYPE_UNKNOWN;
4763 
4764 	if (s == NULL && c != NULL)
4765 		s = c->session;
4766 	if (wl == NULL && s != NULL)
4767 		wl = s->curw;
4768 	if (wp == NULL && wl != NULL)
4769 		wp = wl->window->active;
4770 
4771 	if (c != NULL)
4772 		format_defaults_client(ft, c);
4773 	if (s != NULL)
4774 		format_defaults_session(ft, s);
4775 	if (wl != NULL)
4776 		format_defaults_winlink(ft, wl);
4777 	if (wp != NULL)
4778 		format_defaults_pane(ft, wp);
4779 
4780 	pb = paste_get_top(NULL);
4781 	if (pb != NULL)
4782 		format_defaults_paste_buffer(ft, pb);
4783 }
4784 
4785 /* Set default format keys for a session. */
4786 static void
4787 format_defaults_session(struct format_tree *ft, struct session *s)
4788 {
4789 	ft->s = s;
4790 }
4791 
4792 /* Set default format keys for a client. */
4793 static void
4794 format_defaults_client(struct format_tree *ft, struct client *c)
4795 {
4796 	if (ft->s == NULL)
4797 		ft->s = c->session;
4798 	ft->c = c;
4799 }
4800 
4801 /* Set default format keys for a window. */
4802 void
4803 format_defaults_window(struct format_tree *ft, struct window *w)
4804 {
4805 	ft->w = w;
4806 }
4807 
4808 /* Set default format keys for a winlink. */
4809 static void
4810 format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
4811 {
4812 	if (ft->w == NULL)
4813 		format_defaults_window(ft, wl->window);
4814 	ft->wl = wl;
4815 }
4816 
4817 /* Set default format keys for a window pane. */
4818 void
4819 format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
4820 {
4821 	struct window_mode_entry	*wme;
4822 
4823 	if (ft->w == NULL)
4824 		format_defaults_window(ft, wp->window);
4825 	ft->wp = wp;
4826 
4827 	wme = TAILQ_FIRST(&wp->modes);
4828 	if (wme != NULL && wme->mode->formats != NULL)
4829 		wme->mode->formats(wme, ft);
4830 }
4831 
4832 /* Set default format keys for paste buffer. */
4833 void
4834 format_defaults_paste_buffer(struct format_tree *ft, struct paste_buffer *pb)
4835 {
4836 	ft->pb = pb;
4837 }
4838 
4839 /* Return word at given coordinates. Caller frees. */
4840 char *
4841 format_grid_word(struct grid *gd, u_int x, u_int y)
4842 {
4843 	const struct grid_line	*gl;
4844 	struct grid_cell	 gc;
4845 	const char		*ws;
4846 	struct utf8_data	*ud = NULL;
4847 	u_int			 end;
4848 	size_t			 size = 0;
4849 	int			 found = 0;
4850 	char			*s = NULL;
4851 
4852 	ws = options_get_string(global_s_options, "word-separators");
4853 
4854 	for (;;) {
4855 		grid_get_cell(gd, x, y, &gc);
4856 		if (gc.flags & GRID_FLAG_PADDING)
4857 			break;
4858 		if (utf8_cstrhas(ws, &gc.data) ||
4859 		    (gc.data.size == 1 && *gc.data.data == ' ')) {
4860 			found = 1;
4861 			break;
4862 		}
4863 
4864 		if (x == 0) {
4865 			if (y == 0)
4866 				break;
4867 			gl = grid_peek_line(gd, y - 1);
4868 			if (~gl->flags & GRID_LINE_WRAPPED)
4869 				break;
4870 			y--;
4871 			x = grid_line_length(gd, y);
4872 			if (x == 0)
4873 				break;
4874 		}
4875 		x--;
4876 	}
4877 	for (;;) {
4878 		if (found) {
4879 			end = grid_line_length(gd, y);
4880 			if (end == 0 || x == end - 1) {
4881 				if (y == gd->hsize + gd->sy - 1)
4882 					break;
4883 				gl = grid_peek_line(gd, y);
4884 				if (~gl->flags & GRID_LINE_WRAPPED)
4885 					break;
4886 				y++;
4887 				x = 0;
4888 			} else
4889 				x++;
4890 		}
4891 		found = 1;
4892 
4893 		grid_get_cell(gd, x, y, &gc);
4894 		if (gc.flags & GRID_FLAG_PADDING)
4895 			break;
4896 		if (utf8_cstrhas(ws, &gc.data) ||
4897 		    (gc.data.size == 1 && *gc.data.data == ' '))
4898 			break;
4899 
4900 		ud = xreallocarray(ud, size + 2, sizeof *ud);
4901 		memcpy(&ud[size++], &gc.data, sizeof *ud);
4902 	}
4903 	if (size != 0) {
4904 		ud[size].size = 0;
4905 		s = utf8_tocstr(ud);
4906 		free(ud);
4907 	}
4908 	return (s);
4909 }
4910 
4911 /* Return line at given coordinates. Caller frees. */
4912 char *
4913 format_grid_line(struct grid *gd, u_int y)
4914 {
4915 	struct grid_cell	 gc;
4916 	struct utf8_data	*ud = NULL;
4917 	u_int			 x;
4918 	size_t			 size = 0;
4919 	char			*s = NULL;
4920 
4921 	for (x = 0; x < grid_line_length(gd, y); x++) {
4922 		grid_get_cell(gd, x, y, &gc);
4923 		if (gc.flags & GRID_FLAG_PADDING)
4924 			break;
4925 
4926 		ud = xreallocarray(ud, size + 2, sizeof *ud);
4927 		memcpy(&ud[size++], &gc.data, sizeof *ud);
4928 	}
4929 	if (size != 0) {
4930 		ud[size].size = 0;
4931 		s = utf8_tocstr(ud);
4932 		free(ud);
4933 	}
4934 	return (s);
4935 }
4936