From 40276648ab31822068c3408ae43a5ecaafd03a5c Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Tue, 13 Nov 2007 16:48:10 +0000 Subject: sed: support GNU-like '\t' escape in substitutions --- editors/sed.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'editors') diff --git a/editors/sed.c b/editors/sed.c index f75fceea5..0f5cab2b7 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -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(); -- cgit v1.2.3