Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/sed sed(1): Don't force a newline on last line, if i...



details:   https://anonhg.NetBSD.org/src/rev/48f99a9e59d5
branches:  trunk
changeset: 1010141:48f99a9e59d5
user:      christos <christos%NetBSD.org@localhost>
date:      Fri May 15 22:39:54 2020 +0000

description:
sed(1): Don't force a newline on last line, if input stream doesn't have one

While here, change how we check if the current line is the last one.
Before, we just checked if there were more files after the current one.
Now, we check the actual content of those files: they files may not have
a line at all. This matches the definition of the "last line" by the
Open Group.

The new behavior is closer to GNU sed.

>From FreeBSD (9dd857db3dc558dc61dc8674d204ebc83cac0739), requested by mrg@

diffstat:

 usr.bin/sed/defs.h    |   3 +-
 usr.bin/sed/main.c    |  54 ++++++++++++++++++++++++++++++++++++++++++++------
 usr.bin/sed/process.c |  20 +++++++++++++++---
 3 files changed, 65 insertions(+), 12 deletions(-)

diffs (192 lines):

diff -r 0202edab7649 -r 48f99a9e59d5 usr.bin/sed/defs.h
--- a/usr.bin/sed/defs.h        Fri May 15 22:35:05 2020 +0000
+++ b/usr.bin/sed/defs.h        Fri May 15 22:39:54 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: defs.h,v 1.12 2014/06/06 21:56:39 wiz Exp $    */
+/*     $NetBSD: defs.h,v 1.13 2020/05/15 22:39:54 christos Exp $       */
 
 /*-
  * Copyright (c) 1992 Diomidis Spinellis.
@@ -145,6 +145,7 @@
        char *space;            /* Current space pointer. */
        size_t len;             /* Current length. */
        int deleted;            /* If deleted. */
+       int append_newline;     /* If originally terminated by \n. */
        char *back;             /* Backing memory. */
        size_t blen;            /* Backing memory length. */
 } SPACE;
diff -r 0202edab7649 -r 48f99a9e59d5 usr.bin/sed/main.c
--- a/usr.bin/sed/main.c        Fri May 15 22:35:05 2020 +0000
+++ b/usr.bin/sed/main.c        Fri May 15 22:39:54 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: main.c,v 1.35 2019/10/05 20:22:36 christos Exp $       */
+/*     $NetBSD: main.c,v 1.36 2020/05/15 22:39:54 christos Exp $       */
 
 /*-
  * Copyright (c) 2013 Johann 'Myrkraverk' Oskarsson.
@@ -39,7 +39,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: main.c,v 1.35 2019/10/05 20:22:36 christos Exp $");
+__RCSID("$NetBSD: main.c,v 1.36 2020/05/15 22:39:54 christos Exp $");
 #ifdef __FBSDID
 __FBSDID("$FreeBSD: head/usr.bin/sed/main.c 252231 2013-06-26 04:14:19Z pfg $");
 #endif
@@ -465,8 +465,14 @@
        ssize_t slen = getline(&p, &plen, infile);
        if (slen == -1)
                err(1, "%s", fname);
-       if (slen != 0 && p[slen - 1] == '\n')
+       if (slen != 0 && p[slen - 1] == '\n') {
+               sp->append_newline = 1;
                slen--;
+       } else if (!lastline()) {
+               sp->append_newline = 1;
+       } else {
+               sp->append_newline = 0;
+       }
        cspace(sp, p, (size_t)slen, spflag);
 
        linenum++;
@@ -505,15 +511,49 @@
        fl_nextp = &fp->next;
 }
 
+static int
+next_files_have_lines(void)
+{
+       struct s_flist *file;
+       FILE *file_fd;
+       int ch;
+
+       file = files;
+       while ((file = file->next) != NULL) {
+               if ((file_fd = fopen(file->fname, "r")) == NULL)
+                       continue;
+
+               if ((ch = getc(file_fd)) != EOF) {
+                       /*
+                        * This next file has content, therefore current
+                        * file doesn't contains the last line.
+                        */
+                       ungetc(ch, file_fd);
+                       fclose(file_fd);
+                       return (1);
+               }
+
+               fclose(file_fd);
+       }
+
+       return (0);
+}
+
 int
 lastline(void)
 {
        int ch;
 
-       if (files->next != NULL && (inplace == NULL || ispan))
-               return (0);
-       if ((ch = getc(infile)) == EOF)
-               return (1);
+       if (feof(infile)) {
+               return !(
+                   (inplace == NULL || ispan) &&
+                   next_files_have_lines());
+       }
+       if ((ch = getc(infile)) == EOF) {
+               return !(
+                   (inplace == NULL || ispan) &&
+                   next_files_have_lines());
+       }
        ungetc(ch, infile);
        return (0);
 }
diff -r 0202edab7649 -r 48f99a9e59d5 usr.bin/sed/process.c
--- a/usr.bin/sed/process.c     Fri May 15 22:35:05 2020 +0000
+++ b/usr.bin/sed/process.c     Fri May 15 22:39:54 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: process.c,v 1.52 2015/03/12 12:40:41 christos Exp $    */
+/*     $NetBSD: process.c,v 1.53 2020/05/15 22:39:54 christos Exp $    */
 
 /*-
  * Copyright (c) 1992 Diomidis Spinellis.
@@ -38,7 +38,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: process.c,v 1.52 2015/03/12 12:40:41 christos Exp $");
+__RCSID("$NetBSD: process.c,v 1.53 2020/05/15 22:39:54 christos Exp $");
 #ifdef __FBSDID
 __FBSDID("$FreeBSD: head/usr.bin/sed/process.c 192732 2009-05-25 06:45:33Z brian $");
 #endif
@@ -72,6 +72,7 @@
 #define        pd              PS.deleted
 #define        ps              PS.space
 #define        psl             PS.len
+#define        psanl           PS.append_newline
 #define        hs              HS.space
 #define        hsl             HS.len
 
@@ -94,7 +95,10 @@
 size_t maxnsub;
 regmatch_t *match;
 
-#define OUT() do {fwrite(ps, 1, psl, outfile); fputc('\n', outfile);} while (0)
+#define OUT() do {                                                     \
+       fwrite(ps, 1, psl, outfile);                                    \
+       if (psanl) fputc('\n', outfile);                                \
+} while (0)
 
 void
 process(void)
@@ -103,6 +107,7 @@
        SPACE tspace;
        size_t oldpsl = 0;
        char *p;
+       int oldpsanl;
 
        p = NULL;
 
@@ -198,11 +203,15 @@
                                        break;
                                if ((p = memchr(ps, '\n', psl - 1)) != NULL) {
                                        oldpsl = psl;
+                                       oldpsanl = psanl;
                                        psl = (size_t)(p - ps);
+                                       psanl = 1;
                                }
                                OUT();
-                               if (p != NULL)
+                               if (p != NULL) {
                                        psl = oldpsl;
+                                       psanl = oldpsanl;
+                               }
                                break;
                        case 'q':
                                if (!nflag && !pd)
@@ -251,6 +260,7 @@
                                        cspace(&HS, "", 0, REPLACE);
                                tspace = PS;
                                PS = HS;
+                               psanl = tspace.append_newline;
                                HS = tspace;
                                break;
                        case 'y':
@@ -459,6 +469,7 @@
         */
        tspace = PS;
        PS = SS;
+       psanl = tspace.append_newline;
        SS = tspace;
        SS.space = SS.back;
 
@@ -528,6 +539,7 @@
                /* Swap the translation space and the pattern space. */
                tmp = PS;
                PS = YS;
+               psanl = tmp.append_newline;
                YS = tmp;
                YS.space = YS.back;
        }



Home | Main Index | Thread Index | Old Index