diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2016-11-27 21:09:44 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2016-11-27 21:09:44 +0100 |
| commit | 6a566b9cf5aa38f5f0d4e03c98c84e3a86961e9c (patch) | |
| tree | 06ab86bc8a9944c477f2c82d523a4130e20f79b5 /sam.c | |
| parent | ce66ec2833143cc14eb6cffc6f16b736df9d1f31 (diff) | |
| download | vis-6a566b9cf5aa38f5f0d4e03c98c84e3a86961e9c.tar.gz vis-6a566b9cf5aa38f5f0d4e03c98c84e3a86961e9c.tar.xz | |
sam: stricter command parsing
Properly detect unbalanced curly braces and spurious output at the
end of a group.
Diffstat (limited to 'sam.c')
| -rw-r--r-- | sam.c | 25 |
1 files changed, 20 insertions, 5 deletions
@@ -404,6 +404,7 @@ const char *sam_error(enum SamError err) { [SAM_ERR_SHELL] = "Shell command expected", [SAM_ERR_COMMAND] = "Unknown command", [SAM_ERR_EXECUTE] = "Error executing command", + [SAM_ERR_NEWLINE] = "Newline expected", }; return err < LENGTH(error_msg) ? error_msg[err] : NULL; @@ -695,7 +696,7 @@ static const CommandDef *command_lookup(Vis *vis, const char *name) { return map_closest(vis->cmds, name); } -static Command *command_parse(Vis *vis, const char **s, int level, enum SamError *err) { +static Command *command_parse(Vis *vis, const char **s, enum SamError *err) { if (!**s) { *err = SAM_ERR_COMMAND; return NULL; @@ -727,17 +728,22 @@ static Command *command_parse(Vis *vis, const char **s, int level, enum SamError if (strcmp(cmd->argv[0], "{") == 0) { Command *prev = NULL, *next; + int level = vis->nesting_level++; do { while (**s == ' ' || **s == '\t' || **s == '\n') (*s)++; - next = command_parse(vis, s, level+1, err); + next = command_parse(vis, s, err); if (prev) prev->next = next; else cmd->cmd = next; } while ((prev = next)); + if (level != vis->nesting_level) { + *err = SAM_ERR_UNMATCHED_BRACE; + goto fail; + } } else if (strcmp(cmd->argv[0], "}") == 0) { - if (level == 0) { + if (vis->nesting_level-- == 0) { *err = SAM_ERR_UNMATCHED_BRACE; goto fail; } @@ -791,7 +797,7 @@ static Command *command_parse(Vis *vis, const char **s, int level, enum SamError goto fail; cmd->cmd->cmddef = command_lookup(vis, cmddef->defcmd); } else { - if (!(cmd->cmd = command_parse(vis, s, level, err))) + if (!(cmd->cmd = command_parse(vis, s, err))) goto fail; if (strcmp(cmd->argv[0], "X") == 0 || strcmp(cmd->argv[0], "Y") == 0) { Command *sel = command_new("s"); @@ -811,10 +817,19 @@ fail: } static Command *sam_parse(Vis *vis, const char *cmd, enum SamError *err) { + vis->nesting_level = 0; const char **s = &cmd; - Command *c = command_parse(vis, s, 0, err); + Command *c = command_parse(vis, s, err); if (!c) return NULL; + while (**s == ' ' || **s == '\t' || **s == '\n') + (*s)++; + if (**s) { + *err = SAM_ERR_NEWLINE; + command_free(c); + return NULL; + } + Command *sel = command_new("s"); if (!sel) { command_free(c); |
