sed: make 's///w FILE' actually write to FILE. Closes 8251
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 24 Jan 2016 14:52:16 +0000 (15:52 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 24 Jan 2016 14:52:16 +0000 (15:52 +0100)
function                                             old     new   delta
add_cmd                                             1167    1210     +43

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
editors/sed.c
testsuite/sed.tests

index a8c35388b0fcbd0d1342e37a661f3c2fc19fddb3..4c7f75521f768f8f8b01913aeb324b5cfd873880 100644 (file)
@@ -113,7 +113,7 @@ typedef struct sed_cmd_s {
        int end_line;           /* 'sed 1,3p' 0 == one line only. -1 = last line ($). -2-N = +N */
        int end_line_orig;
 
-       FILE *sw_file;          /* File (sw) command writes to, -1 for none. */
+       FILE *sw_file;          /* File (sw) command writes to, NULL for none. */
        char *string;           /* Data string for (saicytb) commands. */
 
        unsigned which_match;   /* (s) Which match to replace (0 for all) */
@@ -179,7 +179,7 @@ static void sed_free_and_close_stuff(void)
                sed_cmd_t *sed_cmd_next = sed_cmd->next;
 
                if (sed_cmd->sw_file)
-                       xprint_and_close_file(sed_cmd->sw_file);
+                       fclose(sed_cmd->sw_file);
 
                if (sed_cmd->beg_match) {
                        regfree(sed_cmd->beg_match);
@@ -426,8 +426,11 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr)
                /* Write to file */
                case 'w':
                {
-                       char *temp;
-                       idx += parse_file_cmd(/*sed_cmd,*/ substr+idx, &temp);
+                       char *fname;
+                       idx += parse_file_cmd(/*sed_cmd,*/ substr+idx+1, &fname);
+                       sed_cmd->sw_file = xfopen_for_write(fname);
+                       sed_cmd->sw_last_char = '\n';
+                       free(fname);
                        break;
                }
                /* Ignore case (gnu exension) */
index 34479e55f090f6bae5c86b0909ff1de6fec70346..5d2356b641445b01dc02dab2d7f4c072d67ef46a 100755 (executable)
@@ -365,6 +365,12 @@ testing "sed /regex/,+0<cmd> -i works" \
        "1\n2\n3\n4\n5\n6\n7\n8\n" \
        "1\n2\n4\n5\n6\n7\n8\n" \
 
+testing "sed 's///w FILE'" \
+       "sed 's/qwe/ZZZ/wz'; cat z; rm z" \
+       "123\nZZZ\nasd\n""ZZZ\n" \
+       "" \
+       "123\nqwe\nasd\n"
+
 # testing "description" "commands" "result" "infile" "stdin"
 
 exit $FAILCOUNT