mirror of
https://github.com/tmux/tmux.git
synced 2026-07-03 10:22:29 +00:00
Better version.
This commit is contained in:
85
cmd-parse.y
85
cmd-parse.y
@@ -756,65 +756,6 @@ cmd_parse_from_arguments_add(struct cmd_parse_node *seq,
|
||||
TAILQ_INSERT_TAIL(&(*cmd)->children, child, entry);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add one argv string, splitting unescaped ; as command separators:
|
||||
*
|
||||
* A single ; starts another command in the same sequence.
|
||||
* A double ;; starts another sequence.
|
||||
* A \; is kept as a literal semicolon in the argument.
|
||||
*/
|
||||
static void
|
||||
cmd_parse_from_argument_string(struct cmd_parse_node *root,
|
||||
struct cmd_parse_node **seq, struct cmd_parse_node **cmd, const char *s)
|
||||
{
|
||||
char *buf;
|
||||
size_t len = 0;
|
||||
struct cmd_parse_node *child;
|
||||
const char *cp;
|
||||
|
||||
buf = xmalloc(1);
|
||||
*buf = '\0';
|
||||
|
||||
for (cp = s; *cp != '\0'; cp++) {
|
||||
if (*cp == '\\' && cp[1] != '\0') {
|
||||
cp++;
|
||||
buf = xrealloc(buf, len + 2);
|
||||
buf[len++] = *cp;
|
||||
buf[len] = '\0';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*cp != ';') {
|
||||
buf = xrealloc(buf, len + 2);
|
||||
buf[len++] = *cp;
|
||||
buf[len] = '\0';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len != 0) {
|
||||
child = cmd_parse_new_string_node(buf, 0);
|
||||
cmd_parse_from_arguments_add(*seq, cmd, child);
|
||||
len = 0;
|
||||
*buf = '\0';
|
||||
}
|
||||
|
||||
if (cp[1] == ';') {
|
||||
*cmd = NULL;
|
||||
*seq = cmd_parse_new_node(CMD_PARSE_SEQUENCE, 0);
|
||||
TAILQ_INSERT_TAIL(&root->children, *seq, entry);
|
||||
cp++;
|
||||
} else
|
||||
*cmd = NULL;
|
||||
}
|
||||
|
||||
if (len != 0) {
|
||||
child = cmd_parse_new_string_node(buf, 0);
|
||||
cmd_parse_from_arguments_add(*seq, cmd, child);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/* Build a parse tree directly from existing argument values. */
|
||||
struct cmd_parse_tree *
|
||||
cmd_parse_from_arguments(struct args_value *values, u_int count)
|
||||
@@ -822,18 +763,37 @@ cmd_parse_from_arguments(struct args_value *values, u_int count)
|
||||
struct cmd_parse_tree *new;
|
||||
struct cmd_parse_node *root, *seq, *cmd = NULL, *child;
|
||||
u_int i;
|
||||
char *copy;
|
||||
size_t size;
|
||||
int end;
|
||||
|
||||
root = cmd_parse_new_node(CMD_PARSE_ROOT, 0);
|
||||
seq = cmd_parse_new_node(CMD_PARSE_SEQUENCE, 0);
|
||||
TAILQ_INSERT_TAIL(&root->children, seq, entry);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
end = 0;
|
||||
|
||||
switch (values[i].type) {
|
||||
case ARGS_NONE:
|
||||
continue;
|
||||
case ARGS_STRING:
|
||||
cmd_parse_from_argument_string(root, &seq, &cmd,
|
||||
values[i].string);
|
||||
copy = xstrdup(values[i].string);
|
||||
size = strlen(copy);
|
||||
|
||||
if (size != 0 && copy[size - 1] == ';') {
|
||||
copy[--size] = '\0';
|
||||
if (size > 0 && copy[size - 1] == '\\')
|
||||
copy[size - 1] = ';';
|
||||
else
|
||||
end = 1;
|
||||
}
|
||||
|
||||
if (!end || size != 0) {
|
||||
child = cmd_parse_new_string_node(copy, 0);
|
||||
cmd_parse_from_arguments_add(seq, &cmd, child);
|
||||
}
|
||||
free(copy);
|
||||
break;
|
||||
case ARGS_COMMANDS:
|
||||
child = cmd_parse_new_commands_node(values[i].cmd, 0);
|
||||
@@ -842,6 +802,9 @@ cmd_parse_from_arguments(struct args_value *values, u_int count)
|
||||
default:
|
||||
fatalx("unknown argument type");
|
||||
}
|
||||
|
||||
if (end)
|
||||
cmd = NULL;
|
||||
}
|
||||
|
||||
new = xcalloc(1, sizeof *new);
|
||||
|
||||
Reference in New Issue
Block a user