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,