version 1.27, 2013/03/22 15:54:29 |
version 1.28, 2013/03/24 09:54:10 |
|
|
|
|
#include "tmux.h" |
#include "tmux.h" |
|
|
/* |
struct cmd_q *cfg_cmd_q; |
* Config file parser. Pretty quick and simple, each line is parsed into a |
|
* argv array and executed as a command. |
|
*/ |
|
|
|
void printflike2 cfg_print(struct cmd_ctx *, const char *, ...); |
|
void printflike2 cfg_error(struct cmd_ctx *, const char *, ...); |
|
|
|
char *cfg_cause; |
|
int cfg_finished; |
int cfg_finished; |
int cfg_references; |
int cfg_references; |
struct causelist cfg_causes; |
struct causelist cfg_causes; |
|
|
void printflike2 |
int |
cfg_print(unused struct cmd_ctx *ctx, unused const char *fmt, ...) |
load_cfg(const char *path, struct cmd_q *cmdq, char **cause) |
{ |
{ |
} |
|
|
|
void printflike2 |
|
cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...) |
|
{ |
|
va_list ap; |
|
|
|
va_start(ap, fmt); |
|
xvasprintf(&cfg_cause, fmt, ap); |
|
va_end(ap); |
|
} |
|
|
|
void printflike2 |
|
cfg_add_cause(struct causelist *causes, const char *fmt, ...) |
|
{ |
|
char *cause; |
|
va_list ap; |
|
|
|
va_start(ap, fmt); |
|
xvasprintf(&cause, fmt, ap); |
|
va_end(ap); |
|
|
|
ARRAY_ADD(causes, cause); |
|
} |
|
|
|
/* |
|
* Load configuration file. Returns -1 for an error with a list of messages in |
|
* causes. Note that causes must be initialised by the caller! |
|
*/ |
|
enum cmd_retval |
|
load_cfg(const char *path, struct cmd_ctx *ctx, struct causelist *causes) |
|
{ |
|
FILE *f; |
FILE *f; |
u_int n; |
u_int n, found; |
char *buf, *copy, *line, *cause; |
char *buf, *copy, *line, *cause1, *msg; |
size_t len, oldlen; |
size_t len, oldlen; |
struct cmd_list *cmdlist; |
struct cmd_list *cmdlist; |
enum cmd_retval retval; |
|
|
|
if ((f = fopen(path, "rb")) == NULL) { |
if ((f = fopen(path, "rb")) == NULL) { |
cfg_add_cause(causes, "%s: %s", path, strerror(errno)); |
xasprintf(cause, "%s: %s", path, strerror(errno)); |
return (CMD_RETURN_ERROR); |
return (-1); |
} |
} |
|
|
cfg_references++; |
n = found = 0; |
|
|
if (ctx != NULL) |
|
cmd_ref_ctx(ctx); |
|
else { |
|
ctx = cmd_get_ctx(NULL, NULL); |
|
ctx->error = cfg_error; |
|
ctx->print = cfg_print; |
|
ctx->info = cfg_print; |
|
} |
|
|
|
n = 0; |
|
line = NULL; |
line = NULL; |
retval = CMD_RETURN_NORMAL; |
|
while ((buf = fgetln(f, &len))) { |
while ((buf = fgetln(f, &len))) { |
/* Trim \n. */ |
/* Trim \n. */ |
if (buf[len - 1] == '\n') |
if (buf[len - 1] == '\n') |
|
|
continue; |
continue; |
} |
} |
|
|
if (cmd_string_parse(buf, &cmdlist, &cause) != 0) { |
/* Parse and run the command. */ |
|
if (cmd_string_parse(buf, &cmdlist, path, n, &cause1) != 0) { |
free(copy); |
free(copy); |
if (cause == NULL) |
if (cause1 == NULL) |
continue; |
continue; |
cfg_add_cause(causes, "%s: %u: %s", path, n, cause); |
xasprintf(&msg, "%s:%u: %s", path, n, cause1); |
free(cause); |
ARRAY_ADD(&cfg_causes, msg); |
|
free(cause1); |
continue; |
continue; |
} |
} |
free(copy); |
free(copy); |
|
|
if (cmdlist == NULL) |
if (cmdlist == NULL) |
continue; |
continue; |
|
cmdq_append(cmdq, cmdlist); |
cfg_cause = NULL; |
|
switch (cmd_list_exec(cmdlist, ctx)) { |
|
case CMD_RETURN_YIELD: |
|
if (retval != CMD_RETURN_ATTACH) |
|
retval = CMD_RETURN_YIELD; |
|
break; |
|
case CMD_RETURN_ATTACH: |
|
retval = CMD_RETURN_ATTACH; |
|
break; |
|
case CMD_RETURN_ERROR: |
|
case CMD_RETURN_NORMAL: |
|
break; |
|
} |
|
cmd_list_free(cmdlist); |
cmd_list_free(cmdlist); |
if (cfg_cause != NULL) { |
found++; |
cfg_add_cause(causes, "%s: %d: %s", path, n, cfg_cause); |
|
free(cfg_cause); |
|
} |
|
} |
} |
if (line != NULL) { |
if (line != NULL) |
cfg_add_cause(causes, |
|
"%s: %d: line continuation at end of file", path, n); |
|
free(line); |
free(line); |
} |
|
fclose(f); |
fclose(f); |
|
|
cmd_free_ctx(ctx); |
return (found); |
|
} |
|
|
cfg_references--; |
void |
|
cfg_default_done(unused struct cmd_q *cmdq) |
|
{ |
|
if (--cfg_references != 0) |
|
return; |
|
cfg_finished = 1; |
|
|
return (retval); |
if (!RB_EMPTY(&sessions)) |
|
cfg_show_causes(RB_MIN(sessions, &sessions)); |
|
|
|
cmdq_free(cfg_cmd_q); |
|
cfg_cmd_q = NULL; |
} |
} |
|
|
void |
void |
show_cfg_causes(struct session *s) |
cfg_show_causes(struct session *s) |
{ |
{ |
struct window_pane *wp; |
struct window_pane *wp; |
char *cause; |
char *cause; |
|
|
|
|
if (s == NULL || ARRAY_EMPTY(&cfg_causes)) |
if (s == NULL || ARRAY_EMPTY(&cfg_causes)) |
return; |
return; |
|
|
wp = s->curw->window->active; |
wp = s->curw->window->active; |
|
|
window_pane_set_mode(wp, &window_copy_mode); |
window_pane_set_mode(wp, &window_copy_mode); |