aboutsummaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorJean-Sébastien Pédron <dumbbell@FreeBSD.org>2014-08-08 17:29:01 +0000
committerJean-Sébastien Pédron <dumbbell@FreeBSD.org>2014-08-08 17:29:01 +0000
commit96d68291af30586e0f5ce80b46d5d4e503af15a5 (patch)
tree56fad7945f924294efc11e0543b0c26cd444943a /usr.bin
parent39ffa8c138a37381f273a1d9231cc9b98d4275d0 (diff)
Notes
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/sed/defs.h1
-rw-r--r--usr.bin/sed/main.c50
-rw-r--r--usr.bin/sed/process.c16
-rw-r--r--usr.bin/sed/tests/regress.y.out2
4 files changed, 61 insertions, 8 deletions
diff --git a/usr.bin/sed/defs.h b/usr.bin/sed/defs.h
index d4f434ee84ebf..fb336765d639b 100644
--- a/usr.bin/sed/defs.h
+++ b/usr.bin/sed/defs.h
@@ -143,6 +143,7 @@ typedef struct {
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 --git a/usr.bin/sed/main.c b/usr.bin/sed/main.c
index 6cdfcda936787..76e186f96b8a5 100644
--- a/usr.bin/sed/main.c
+++ b/usr.bin/sed/main.c
@@ -439,8 +439,14 @@ mf_fgets(SPACE *sp, enum e_spflag spflag)
len = getline(&p, &plen, infile);
if (len == -1)
err(1, "%s", fname);
- if (len != 0 && p[len - 1] == '\n')
+ if (len != 0 && p[len - 1] == '\n') {
+ sp->append_newline = 1;
len--;
+ } else if (!lastline()) {
+ sp->append_newline = 1;
+ } else {
+ sp->append_newline = 0;
+ }
cspace(sp, p, len, spflag);
linenum++;
@@ -481,15 +487,49 @@ add_file(char *s)
fl_nextp = &fp->next;
}
+static int
+next_files_have_lines()
+{
+ 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 --git a/usr.bin/sed/process.c b/usr.bin/sed/process.c
index a500200dd87d0..9cd2c2e87b24d 100644
--- a/usr.bin/sed/process.c
+++ b/usr.bin/sed/process.c
@@ -63,6 +63,7 @@ static SPACE HS, PS, SS, YS;
#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
@@ -85,7 +86,10 @@ static regex_t *defpreg;
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)
@@ -94,6 +98,7 @@ process(void)
SPACE tspace;
size_t oldpsl = 0;
char *p;
+ int oldpsanl;
p = NULL;
@@ -190,11 +195,15 @@ redirect:
break;
if ((p = memchr(ps, '\n', psl)) != NULL) {
oldpsl = psl;
+ oldpsanl = psanl;
psl = p - ps;
+ psanl = 1;
}
OUT();
- if (p != NULL)
+ if (p != NULL) {
psl = oldpsl;
+ psanl = oldpsanl;
+ }
break;
case 'q':
if (!nflag && !pd)
@@ -244,6 +253,7 @@ redirect:
cspace(&HS, "", 0, REPLACE);
tspace = PS;
PS = HS;
+ psanl = tspace.append_newline;
HS = tspace;
break;
case 'y':
@@ -452,6 +462,7 @@ substitute(struct s_command *cp)
*/
tspace = PS;
PS = SS;
+ psanl = tspace.append_newline;
SS = tspace;
SS.space = SS.back;
@@ -521,6 +532,7 @@ do_tr(struct s_tr *y)
/* Swap the translation space and the pattern space. */
tmp = PS;
PS = YS;
+ psanl = tmp.append_newline;
YS = tmp;
YS.space = YS.back;
}
diff --git a/usr.bin/sed/tests/regress.y.out b/usr.bin/sed/tests/regress.y.out
index 829a681802766..22f4f051cef18 100644
--- a/usr.bin/sed/tests/regress.y.out
+++ b/usr.bin/sed/tests/regress.y.out
@@ -1 +1 @@
-fOO
+fOO \ No newline at end of file