sed: support GNU-like '\t' escape in substitutions

This commit is contained in:
Denis Vlasenko
2007-11-13 16:48:10 +00:00
parent 6df9e3c9a3
commit 40276648ab
3 changed files with 13 additions and 6 deletions

View File

@@ -173,7 +173,7 @@ static void cleanup_outname(void)
if (G.outname) unlink(G.outname);
}
/* strdup, replacing "\n" with '\n', and "\delimiter" with 'delimiter' */
/* strcpy, replacing "\from" with 'to'. If to is NUL, replacing "\any" with 'any' */
static void parse_escapes(char *dest, const char *string, int len, char from, char to)
{
@@ -188,9 +188,10 @@ static void parse_escapes(char *dest, const char *string, int len, char from, ch
}
*dest++ = string[i++];
}
/* TODO: is it safe wrt a string with trailing '\\' ? */
*dest++ = string[i++];
}
*dest = 0;
*dest = '\0';
}
static char *copy_parsing_escapes(const char *string, int len)
@@ -198,6 +199,8 @@ static char *copy_parsing_escapes(const char *string, int len)
char *dest = xmalloc(len + 1);
parse_escapes(dest, string, len, 'n', '\n');
/* GNU sed also recognizes \t */
parse_escapes(dest, dest, strlen(dest), 't', '\t');
return dest;
}
@@ -205,7 +208,7 @@ static char *copy_parsing_escapes(const char *string, int len)
/*
* index_of_next_unescaped_regexp_delim - walks left to right through a string
* beginning at a specified index and returns the index of the next regular
* expression delimiter (typically a forward * slash ('/')) not preceded by
* expression delimiter (typically a forward slash ('/')) not preceded by
* a backslash ('\'). A negative delimiter disables square bracket checking.
*/
static int index_of_next_unescaped_regexp_delim(int delimiter, const char *str)
@@ -425,7 +428,8 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr)
break;
}
sed_cmd->string = xstrdup(cmdstr);
parse_escapes(sed_cmd->string, sed_cmd->string, strlen(cmdstr), 0, 0);
/* "\anychar" -> "anychar" */
parse_escapes(sed_cmd->string, sed_cmd->string, strlen(cmdstr), '\0', '\0');
cmdstr += strlen(cmdstr);
/* handle file cmds: (r)ead */
} else if (strchr("rw", sed_cmd->cmd)) {
@@ -1337,7 +1341,7 @@ int sed_main(int argc, char **argv)
// FIXME: error check / message?
rename(G.outname, argv[i]);
free(G.outname);
G.outname = 0;
G.outname = NULL;
}
if (G.input_file_count > G.current_input_file)
process_files();