On 8/15/18 8:58 PM, Ingo Schwarze wrote:
> Hi Martijn,
> 
> i agree with Todd that in implementing an option invented by GNU,
> we should follow GNU semantics unless there are very strong reasons
> to diverge.  In this case, GNU -i semantics is maybe not the only
> possibility that could be regarded as reasonable, but it certainly
> isn't unreasonable:  Execute the script independently for each file
> in turn, but let the 'q' command still exit the editor completely,
> rather than just moving to the next file.
> 
> So, i agree with resetting the hold space when moving from one file
> to the next in -i mode.  But i think the variable HS ought to remain
> in process.c and not be moved to extern.h and not be manipulated from
> main.c.
> 
> Instead, there already is a function to reset internal processor
> state when moving to the next file with -i: resetranges().
> Can you add the two lines to clear the hold space into that
> function and resend the diff?
> 
> If you want, you can make the name of the function more generic,
> for example reset_processor().
> 
> Also, in the manual page, while saying that the hold space is reset,
> also mention what happens to line numbers and ranges, be even more
> explicit that all this applies *only* for -i, and avoid the future
> tense, for example like this:
> 
>   In
>   .Fl i
>   mode, line numbers and the hold space are reset between files,
>   and no range extends from one file into the next.
> 
> Finally, in the description of the 'q' command, we can also be
> more explicit:
> 
>   Branch to the end of the script and quit
>   .Nm
>   without starting a new cycle or a new file.
> 
> Yours,
>   Ingo
> 
I send the diff below to Ingo some time ago, but never got a reply.
Maybe someone else is willing to look at it?

Index: extern.h
===================================================================
RCS file: /cvs/src/usr.bin/sed/extern.h,v
retrieving revision 1.13
diff -u -p -r1.13 extern.h
--- extern.h    1 Aug 2017 18:05:53 -0000       1.13
+++ extern.h    23 Aug 2018 08:11:48 -0000
@@ -53,8 +53,9 @@ __dead void error(int, const char *, ...
 void   warning(const char *, ...);
 int     mf_fgets(SPACE *, enum e_spflag);
 int     lastline(void);
+void    finish_file(void);
 void    process(void);
-void    resetranges(void);
+void    resetstate(void);
 char   *strregerror(int, regex_t *);
 void   *xmalloc(size_t);
 void   *xreallocarray(void *, size_t, size_t);
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/sed/main.c,v
retrieving revision 1.37
diff -u -p -r1.37 main.c
--- main.c      11 Jul 2018 06:57:18 -0000      1.37
+++ main.c      23 Aug 2018 08:11:48 -0000
@@ -310,6 +310,30 @@ again:
        return (NULL);
 }
 
+void
+finish_file(void)
+{
+       if (infile != NULL) {
+               fclose(infile);
+               if (*oldfname != '\0') {
+                       if (rename(fname, oldfname) != 0) {
+                               warning("rename()");
+                               unlink(tmpfname);
+                               exit(1);
+                       }
+                       *oldfname = '\0';
+               }
+               if (*tmpfname != '\0') {
+                       if (outfile != NULL && outfile != stdout)
+                               fclose(outfile);
+                       outfile = NULL;
+                       rename(tmpfname, fname);
+                       *tmpfname = '\0';
+               }
+               outfname = NULL;
+       }
+}
+
 /*
  * Like fgets, but go through the list of files chaining them together.
  * Set len to the length of the line.
@@ -347,25 +371,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
                        sp->len = 0;
                        return (0);
                }
-               if (infile != NULL) {
-                       fclose(infile);
-                       if (*oldfname != '\0') {
-                               if (rename(fname, oldfname) != 0) {
-                                       warning("rename()");
-                                       unlink(tmpfname);
-                                       exit(1);
-                               }
-                               *oldfname = '\0';
-                       }
-                       if (*tmpfname != '\0') {
-                               if (outfile != NULL && outfile != stdout)
-                                       fclose(outfile);
-                               outfile = NULL;
-                               rename(tmpfname, fname);
-                               *tmpfname = '\0';
-                       }
-                       outfname = NULL;
-               }
+               finish_file();
                if (firstfile == 0)
                        files = files->next;
                else
@@ -405,7 +411,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
                        fchmod(fileno(outfile), sb.st_mode & ALLPERMS);
                        outfname = tmpfname;
                        linenum = 0;
-                       resetranges();
+                       resetstate();
                } else {
                        outfile = stdout;
                        outfname = "stdout";
Index: process.c
===================================================================
RCS file: /cvs/src/usr.bin/sed/process.c,v
retrieving revision 1.33
diff -u -p -r1.33 process.c
--- process.c   13 Dec 2017 16:06:34 -0000      1.33
+++ process.c   23 Aug 2018 08:11:48 -0000
@@ -196,6 +196,7 @@ redirect:
                                if (!nflag && !pd)
                                        OUT();
                                flush_appends();
+                               finish_file();
                                exit(0);
                        case 'r':
                                if (appendx >= appendnum) {
@@ -312,9 +313,12 @@ applies(struct s_command *cp)
  * Reset all inrange markers.
  */
 void
-resetranges(void)
+resetstate(void)
 {
        struct s_command *cp;
+
+       free(HS.back);
+       memset(&HS, 0, sizeof(HS));
 
        for (cp = prog; cp; cp = cp->code == '{' ? cp->u.c : cp->next)
                if (cp->a2)
Index: sed.1
===================================================================
RCS file: /cvs/src/usr.bin/sed/sed.1,v
retrieving revision 1.56
diff -u -p -r1.56 sed.1
--- sed.1       11 Jul 2018 06:47:38 -0000      1.56
+++ sed.1       23 Aug 2018 08:11:48 -0000
@@ -106,6 +106,9 @@ It is not recommended to give a zero len
 .Ar extension
 when in place editing files, as it risks corruption or partial content
 in situations where disk space is exhausted, etc.
+In
+.Fl i
+mode, the hold space, line numbers, and ranges are reset between files.
 .It Fl r
 An alias for
 .Fl E ,
@@ -392,7 +395,7 @@ Write the pattern space to standard outp
 Write the pattern space, up to the first newline character,
 to the standard output.
 .It [1addr] Ns Ic q
-Branch to the end of the script and quit without starting a new cycle.
+Branch to the end of the script and quit without starting a new cycle or file.
 .It [1addr] Ns Ic r Ar file
 Copy the contents of
 .Ar file

Reply via email to