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