[dev] [vis][RFC][PATCH 1/2 v2] Rework the separation of command name and parameters

From: Silvan Jegen <s.jegen_AT_gmail.com>
Date: Sat, 9 May 2015 18:12:53 +0200

By replacing the first non-alphanumeric character (except '!' which is
replaced by ' ' to get it ignored) with '\0' we distinguish the command
name from the parameters. That way the 'substitute' command (and its alias
's') is properly recognized.

This is somewhat hacky because for the 'substitute' command we afterwards
have to add back an 's' in the correct position of the argument in order
to make 'sed' accept it but it works fine and is simple enough.
---
This is a lot longer than I would like but it seems to be working for now.
As long as we don't have any commands containing non-alphanumeric chars,
we can rely on 'isalnum' to detect the separation of command names
and parameters as done in this patch. Using separators other than '/'
(as long as they are non-alphanumeric...) now works as well.
Without overwriting the '!' with ' ', forceable commands that take
space-separated arguments would not work anymore. The ' ' is ignored when
parsing the command parameters and that lets us work around the problem
(badly).
 vis.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/vis.c b/vis.c
index 628f511..77489f1 100644
--- a/vis.c
+++ b/vis.c
_AT_@ -1740,10 +1740,11 @@ static Command *lookup_cmd(const char *name) {
 
 static bool exec_cmdline_command(const char *cmdline) {
 	enum CmdOpt opt = CMD_OPT_NONE;
-	char *line = strdup(cmdline);
-	char *name = line;
+	char *line = malloc(strlen(cmdline)+2);
 	if (!line)
 		return false;
+	line = strncpy(line, cmdline, strlen(cmdline)+1);
+	char *name = line;
 	Filerange range = parse_range(&name);
 	if (!text_range_valid(&range)) {
 		/* if only one position was given, jump to it */
_AT_@ -1764,15 +1765,17 @@ static bool exec_cmdline_command(const char *cmdline) {
 	while (*name == ' ')
 		name++;
 	char *param = name;
-	while (*param && *param != ' ') {
-		if (*param == '!') {
-			opt |= CMD_OPT_FORCE;
-			break;
-		}
-		param++;
+	while (*param && *param != ' ' && isalnum(*param)) param++;
+
+	if (*param == '!') {
+		opt |= CMD_OPT_FORCE;
+		*param = ' ';
 	}
-	if (*param)
-		*param++ = '\0'; /* truncate by overwriting ' ' or '!' */
+
+	memmove(param+1, param, strlen(param)+1);
+	/* separate command name from parameter by overwriting the first non-
+	 * alphanumeric character (other than '!' which we overwrote already) */
+	*param++ = '\0';
 
 	Command *cmd = lookup_cmd(name);
 	if (!cmd) {
-- 
2.4.0
Received on Sat May 09 2015 - 18:12:53 CEST

This archive was generated by hypermail 2.3.0 : Sat May 09 2015 - 18:24:08 CEST