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