summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2008-07-25 17:20:40 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2008-07-25 17:20:40 +0000
commitba597da72e8a548403f2a86cbe864f6f8c087397 (patch)
tree2c40dc91a642bc993036bc4c6b2a0b062763f980
parent546838ee6567d5fde03571286199068d5ec9b608 (diff)
Environment variables in configuration file.
-rw-r--r--CHANGES17
-rw-r--r--cfg.c6
-rw-r--r--cmd-command-prompt.c6
-rw-r--r--cmd-string.c145
-rw-r--r--tmux.h4
5 files changed, 153 insertions, 25 deletions
diff --git a/CHANGES b/CHANGES
index 55082fb2..aa82a4bf 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,18 @@
+25 July 2008
+
+* Shell variables may now be defined and used in configuration file. Define
+ variables with:
+
+ VAR=1
+
+ And use with:
+
+ renamew ${VAR}
+ renamew "x${VAR}x"
+
+ Also some other fixes to make, for example, "abc""abc" work similarly to
+ the shell.
+
24 July 2008
* Finally lose inconsistently-used SCREEN_DEF* defines.
@@ -621,4 +636,4 @@
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.
-$Id: CHANGES,v 1.154 2008-07-24 21:42:40 nicm Exp $
+$Id: CHANGES,v 1.155 2008-07-25 17:20:40 nicm Exp $
diff --git a/cfg.c b/cfg.c
index 8a6729e5..44f516b7 100644
--- a/cfg.c
+++ b/cfg.c
@@ -1,4 +1,4 @@
-/* $Id: cfg.c,v 1.12 2008-06-21 10:19:36 nicm Exp $ */
+/* $Id: cfg.c,v 1.13 2008-07-25 17:20:40 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -78,11 +78,13 @@ load_cfg(const char *path, char **cause)
}
n++;
- if ((cmd = cmd_string_parse(buf, cause)) == NULL) {
+ if (cmd_string_parse(buf, &cmd, cause) != 0) {
if (*cause == NULL)
continue;
goto error;
}
+ if (cmd == NULL)
+ continue;
cfg_cause = NULL;
ctx.msgdata = NULL;
diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c
index c156002a..d0bc5d9e 100644
--- a/cmd-command-prompt.c
+++ b/cmd-command-prompt.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-command-prompt.c,v 1.4 2008-06-25 20:43:13 nicm Exp $ */
+/* $Id: cmd-command-prompt.c,v 1.5 2008-07-25 17:20:40 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -72,7 +72,7 @@ cmd_command_prompt_callback(void *data, char *s)
if (s == NULL)
return;
- if ((cmd = cmd_string_parse(s, &cause)) == NULL) {
+ if (cmd_string_parse(s, &cmd, &cause) != 0) {
if (cause == NULL)
return;
*cause = toupper((u_char) *cause);
@@ -80,6 +80,8 @@ cmd_command_prompt_callback(void *data, char *s)
xfree(cause);
return;
}
+ if (cmd == NULL)
+ return;
ctx.msgdata = NULL;
ctx.cursession = c->session;
diff --git a/cmd-string.c b/cmd-string.c
index e28cef2d..d50a4b26 100644
--- a/cmd-string.c
+++ b/cmd-string.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-string.c,v 1.3 2008-06-19 21:20:27 nicm Exp $ */
+/* $Id: cmd-string.c,v 1.4 2008-07-25 17:20:40 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -21,6 +21,7 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include "tmux.h"
@@ -29,7 +30,9 @@
*/
int cmd_string_getc(const char *, size_t *);
+void cmd_string_ungetc(const char *, size_t *);
char *cmd_string_string(const char *, size_t *, char, int);
+char *cmd_string_variable(const char *, size_t *);
int
cmd_string_getc(const char *s, size_t *p)
@@ -39,18 +42,34 @@ cmd_string_getc(const char *s, size_t *p)
return (s[(*p)++]);
}
+void
+cmd_string_ungetc(unused const char *s, size_t *p)
+{
+ (*p)--;
+}
+
/*
- * Parse command string. Return command or NULL on error. If returning NULL,
- * cause is error string, or NULL for empty command.
+ * Parse command string. Return -1 on error. If returning 1, cause is error
+ * string, or NULL for empty command.
*/
-struct cmd *
-cmd_string_parse(const char *s, char **cause)
+int
+cmd_string_parse(const char *s, struct cmd **cmd, char **cause)
{
- size_t p;
- int ch, argc;
- char **argv, *buf, *t;
+ size_t p;
+ int ch, argc, rval;
+ char **argv, *buf, *t, *u;
size_t len;
- struct cmd *cmd;
+
+ if ((t = strchr(s, ' ')) == NULL && (t = strchr(s, '\t')) == NULL)
+ t = strchr(s, '\0');
+ if ((u = strchr(s, '=')) != NULL && u < t) {
+ if (putenv(s) != NULL) {
+ xasprintf(cause, "assignment failed: %s", s);
+ return (-1);
+ }
+ *cmd = NULL;
+ return (0);
+ }
argv = NULL;
argc = 0;
@@ -58,9 +77,10 @@ cmd_string_parse(const char *s, char **cause)
buf = NULL;
len = 0;
- cmd = NULL;
-
*cause = NULL;
+
+ *cmd = NULL;
+ rval = -1;
p = 0;
for (;;) {
@@ -69,14 +89,23 @@ cmd_string_parse(const char *s, char **cause)
case '\'':
if ((t = cmd_string_string(s, &p, '\'', 0)) == NULL)
goto error;
- argv = xrealloc(argv, argc + 1, sizeof *argv);
- argv[argc++] = t;
+ buf = xrealloc(buf, 1, len + strlen(t) + 1);
+ strlcpy(buf + len, t, strlen(t) + 1);
+ len += strlen(t);
break;
case '"':
if ((t = cmd_string_string(s, &p, '"', 1)) == NULL)
goto error;
- argv = xrealloc(argv, argc + 1, sizeof *argv);
- argv[argc++] = t;
+ buf = xrealloc(buf, 1, len + strlen(t) + 1);
+ strlcpy(buf + len, t, strlen(t) + 1);
+ len += strlen(t);
+ break;
+ case '$':
+ if ((t = cmd_string_variable(s, &p)) == NULL)
+ goto error;
+ buf = xrealloc(buf, 1, len + strlen(t) + 1);
+ strlcpy(buf + len, t, strlen(t) + 1);
+ len += strlen(t);
break;
case '#':
/* Comment: discard rest of line. */
@@ -102,7 +131,8 @@ cmd_string_parse(const char *s, char **cause)
if (argc == 0)
goto out;
- cmd = cmd_parse(argc, argv, cause);
+ *cmd = cmd_parse(argc, argv, cause);
+ rval = 0;
goto out;
default:
if (len >= SIZE_MAX - 2)
@@ -126,14 +156,14 @@ out:
if (argv != NULL)
xfree(argv);
- return (cmd);
+ return (rval);
}
char *
cmd_string_string(const char *s, size_t *p, char endch, int esc)
{
int ch;
- char *buf;
+ char *buf, *t;
size_t len;
buf = NULL;
@@ -160,6 +190,15 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
break;
}
break;
+ case '$':
+ if (!esc)
+ break;
+ if ((t = cmd_string_variable(s, p)) == NULL)
+ goto error;
+ buf = xrealloc(buf, 1, len + strlen(t) + 1);
+ strlcpy(buf + len, t, strlen(t) + 1);
+ len += strlen(t);
+ continue;
}
if (len >= SIZE_MAX - 2)
@@ -177,3 +216,73 @@ error:
xfree(buf);
return (NULL);
}
+
+char *
+cmd_string_variable(const char *s, size_t *p)
+{
+ int ch, fch;
+ char *buf, *t;
+ size_t len;
+
+#define cmd_string_first(ch) ((ch) == '_' || \
+ ((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z'))
+#define cmd_string_other(ch) ((ch) == '_' || \
+ ((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z') || \
+ ((ch) >= '0' && (ch) <= '9'))
+
+ buf = NULL;
+ len = 0;
+
+ fch = EOF;
+ switch (ch = cmd_string_getc(s, p)) {
+ case EOF:
+ goto error;
+ case '{':
+ fch = '{';
+
+ ch = cmd_string_getc(s, p);
+ if (!cmd_string_first(ch))
+ goto error;
+ /* FALLTHROUGH */
+ default:
+ if (!cmd_string_first(ch)) {
+ xasprintf(&t, "$%c", ch);
+ return (t);
+ }
+
+ buf = xrealloc(buf, 1, len + 1);
+ buf[len++] = ch;
+
+ for(;;) {
+ ch = cmd_string_getc(s, p);
+ if (ch == EOF || !cmd_string_other(ch))
+ break;
+ else {
+ if (len >= SIZE_MAX - 3)
+ goto error;
+ buf = xrealloc(buf, 1, len + 1);
+ buf[len++] = ch;
+ }
+ }
+ }
+
+ if (fch == '{' && ch != '}')
+ goto error;
+ if (ch != EOF && fch != '{')
+ cmd_string_ungetc(s, p); /* ch */
+
+ buf = xrealloc(buf, 1, len + 1);
+ buf[len] = '\0';
+
+ if ((t = getenv(buf)) == NULL) {
+ xfree(buf);
+ return (xstrdup(""));
+ }
+ xfree(buf);
+ return (xstrdup(t));
+
+error:
+ if (buf != NULL)
+ xfree(buf);
+ return (NULL);
+}
diff --git a/tmux.h b/tmux.h
index fa5edde6..40a68c4f 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1,4 +1,4 @@
-/* $Id: tmux.h,v 1.178 2008-07-24 22:21:28 nicm Exp $ */
+/* $Id: tmux.h,v 1.179 2008-07-25 17:20:40 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -1025,7 +1025,7 @@ extern const struct cmd_entry cmd_unbind_key_entry;
extern const struct cmd_entry cmd_unlink_window_entry;
/* cmd-string.c */
-struct cmd *cmd_string_parse(const char *, char **);
+int cmd_string_parse(const char *, struct cmd **, char **);
/* cmd-generic.c */
#define CMD_TARGET_WINDOW_USAGE "[-t target-window]"