Environment variables in configuration file.

This commit is contained in:
Nicholas Marriott 2008-07-25 17:20:40 +00:00
parent 546838ee65
commit ba597da72e
5 changed files with 155 additions and 27 deletions

17
CHANGES
View File

@ -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 24 July 2008
* Finally lose inconsistently-used SCREEN_DEF* defines. * Finally lose inconsistently-used SCREEN_DEF* defines.
@ -621,4 +636,4 @@
(including mutt, emacs). No status bar yet and no key remapping or other (including mutt, emacs). No status bar yet and no key remapping or other
customisation. 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 $

6
cfg.c
View File

@ -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> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -78,11 +78,13 @@ load_cfg(const char *path, char **cause)
} }
n++; n++;
if ((cmd = cmd_string_parse(buf, cause)) == NULL) { if (cmd_string_parse(buf, &cmd, cause) != 0) {
if (*cause == NULL) if (*cause == NULL)
continue; continue;
goto error; goto error;
} }
if (cmd == NULL)
continue;
cfg_cause = NULL; cfg_cause = NULL;
ctx.msgdata = NULL; ctx.msgdata = NULL;

View File

@ -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> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -72,7 +72,7 @@ cmd_command_prompt_callback(void *data, char *s)
if (s == NULL) if (s == NULL)
return; return;
if ((cmd = cmd_string_parse(s, &cause)) == NULL) { if (cmd_string_parse(s, &cmd, &cause) != 0) {
if (cause == NULL) if (cause == NULL)
return; return;
*cause = toupper((u_char) *cause); *cause = toupper((u_char) *cause);
@ -80,6 +80,8 @@ cmd_command_prompt_callback(void *data, char *s)
xfree(cause); xfree(cause);
return; return;
} }
if (cmd == NULL)
return;
ctx.msgdata = NULL; ctx.msgdata = NULL;
ctx.cursession = c->session; ctx.cursession = c->session;

View File

@ -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> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -21,6 +21,7 @@
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
#include "tmux.h" #include "tmux.h"
@ -29,7 +30,9 @@
*/ */
int cmd_string_getc(const char *, size_t *); 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_string(const char *, size_t *, char, int);
char *cmd_string_variable(const char *, size_t *);
int int
cmd_string_getc(const char *s, size_t *p) 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)++]); 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, * Parse command string. Return -1 on error. If returning 1, cause is error
* cause is error string, or NULL for empty command. * string, or NULL for empty command.
*/ */
struct cmd * int
cmd_string_parse(const char *s, char **cause) cmd_string_parse(const char *s, struct cmd **cmd, char **cause)
{ {
size_t p; size_t p;
int ch, argc; int ch, argc, rval;
char **argv, *buf, *t; char **argv, *buf, *t, *u;
size_t len; 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; argv = NULL;
argc = 0; argc = 0;
@ -58,10 +77,11 @@ cmd_string_parse(const char *s, char **cause)
buf = NULL; buf = NULL;
len = 0; len = 0;
cmd = NULL;
*cause = NULL; *cause = NULL;
*cmd = NULL;
rval = -1;
p = 0; p = 0;
for (;;) { for (;;) {
ch = cmd_string_getc(s, &p); ch = cmd_string_getc(s, &p);
@ -69,14 +89,23 @@ cmd_string_parse(const char *s, char **cause)
case '\'': case '\'':
if ((t = cmd_string_string(s, &p, '\'', 0)) == NULL) if ((t = cmd_string_string(s, &p, '\'', 0)) == NULL)
goto error; goto error;
argv = xrealloc(argv, argc + 1, sizeof *argv); buf = xrealloc(buf, 1, len + strlen(t) + 1);
argv[argc++] = t; strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
break; break;
case '"': case '"':
if ((t = cmd_string_string(s, &p, '"', 1)) == NULL) if ((t = cmd_string_string(s, &p, '"', 1)) == NULL)
goto error; goto error;
argv = xrealloc(argv, argc + 1, sizeof *argv); buf = xrealloc(buf, 1, len + strlen(t) + 1);
argv[argc++] = t; 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; break;
case '#': case '#':
/* Comment: discard rest of line. */ /* Comment: discard rest of line. */
@ -102,7 +131,8 @@ cmd_string_parse(const char *s, char **cause)
if (argc == 0) if (argc == 0)
goto out; goto out;
cmd = cmd_parse(argc, argv, cause); *cmd = cmd_parse(argc, argv, cause);
rval = 0;
goto out; goto out;
default: default:
if (len >= SIZE_MAX - 2) if (len >= SIZE_MAX - 2)
@ -126,14 +156,14 @@ out:
if (argv != NULL) if (argv != NULL)
xfree(argv); xfree(argv);
return (cmd); return (rval);
} }
char * char *
cmd_string_string(const char *s, size_t *p, char endch, int esc) cmd_string_string(const char *s, size_t *p, char endch, int esc)
{ {
int ch; int ch;
char *buf; char *buf, *t;
size_t len; size_t len;
buf = NULL; buf = NULL;
@ -160,6 +190,15 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
break; break;
} }
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) if (len >= SIZE_MAX - 2)
@ -177,3 +216,73 @@ error:
xfree(buf); xfree(buf);
return (NULL); 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);
}

4
tmux.h
View File

@ -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> * 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; extern const struct cmd_entry cmd_unlink_window_entry;
/* cmd-string.c */ /* cmd-string.c */
struct cmd *cmd_string_parse(const char *, char **); int cmd_string_parse(const char *, struct cmd **, char **);
/* cmd-generic.c */ /* cmd-generic.c */
#define CMD_TARGET_WINDOW_USAGE "[-t target-window]" #define CMD_TARGET_WINDOW_USAGE "[-t target-window]"