According to POSIX[0]:
The standard input shall be used if no file operands are specified, and 
shall be used if a file operand is '-' and the implementation treats the
'-' as meaning standard input. Otherwise, the standard input shall not  
be used. See the INPUT FILES section.

Which we currently don't support:
$ cat /tmp/test 
test
$ printf "foo\ntest\nbaz\n" | sed "s/test/bar/" - /tmp/test
sed: 0: -: No such file or directory
bar

So let's fix that while reducing the LoC.
I choose too accept stdin with the -i flag, because:
1) It allows us to combine it as an inplace editor and filter in a
   single operation.
2) It further simplifies the code.

So now we can do fancy stuff like:
$ printf "foo\ntest\nbaz\n" | ./sed "s/test/bar/" /tmp/test -
bar
foo
bar
baz

and
$ printf "foo\ntest\nbaz\n" | ./sed -i "s/test/bar/" /tmp/test -
foo
bar
baz
$ cat /tmp/test 
bar

Note that gsed does support the "-" filename, but treats - in
combination with -i as a filename, instead of stdin:
$ echo test > -
$ gsed -i s/test/bar/ -
$ cat ./-
bar

OK?

martijn@

Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/sed/main.c,v
retrieving revision 1.38
diff -u -p -r1.38 main.c
--- main.c      14 Nov 2018 10:59:33 -0000      1.38
+++ main.c      6 Dec 2018 07:28:15 -0000
@@ -345,32 +345,13 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
        size_t len;
        char *p;
        int c, fd;
-       static int firstfile;
-
-       if (infile == NULL) {
-               /* stdin? */
-               if (files->fname == NULL) {
-                       if (inplace != NULL)
-                               error(FATAL, "-i may not be used with stdin");
-                       infile = stdin;
-                       fname = "stdin";
-                       outfile = stdout;
-                       outfname = "stdout";
-               }
-
-               firstfile = 1;
-       }
+       static int firstfile = 1;
 
        for (;;) {
                if (infile != NULL && (c = getc(infile)) != EOF) {
                        (void)ungetc(c, infile);
                        break;
                }
-               /* If we are here then either eof or no files are open yet */
-               if (infile == stdin) {
-                       sp->len = 0;
-                       return (0);
-               }
                finish_file();
                if (firstfile == 0)
                        files = files->next;
@@ -381,6 +362,13 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
                        return (0);
                }
                fname = files->fname;
+               if (fname == NULL || strcmp(fname, "-") == 0) {
+                       infile = stdin;
+                       fname = "stdin";
+                       outfile = stdout;
+                       outfname = "stdout";
+                       break;
+               }
                if (inplace != NULL) {
                        if (lstat(fname, &sb) != 0)
                                error(FATAL, "%s: %s", fname,

Reply via email to