summaryrefslogtreecommitdiffstats
path: root/usr.bin/sed
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2002-07-03 14:38:27 +0000
committertjr <tjr@FreeBSD.org>2002-07-03 14:38:27 +0000
commit110c2de07c405176de37d5a49c2173d05a37ae84 (patch)
tree0e9ba14e2435a6c3a79c7799f5cbca8f4bf3554e /usr.bin/sed
parentf71af381af338a718b4808374ec0fa5be8193bc3 (diff)
downloadFreeBSD-src-110c2de07c405176de37d5a49c2173d05a37ae84.zip
FreeBSD-src-110c2de07c405176de37d5a49c2173d05a37ae84.tar.gz
Avoid checking whether each line is the last line of the file when we don't
need to know. Instead, check when we are trying to match a "$" address. This does not change the way sed processes regular files, but makes it behave more sensibly when used interactively. PR: 40101 MFC after: 2 weeks
Diffstat (limited to 'usr.bin/sed')
-rw-r--r--usr.bin/sed/extern.h2
-rw-r--r--usr.bin/sed/main.c50
-rw-r--r--usr.bin/sed/process.c2
3 files changed, 29 insertions, 25 deletions
diff --git a/usr.bin/sed/extern.h b/usr.bin/sed/extern.h
index a0ad39b..c908eb1 100644
--- a/usr.bin/sed/extern.h
+++ b/usr.bin/sed/extern.h
@@ -44,7 +44,6 @@ extern regmatch_t *match;
extern size_t maxnsub;
extern u_long linenum;
extern int appendnum;
-extern int lastline;
extern int aflag, eflag, nflag;
extern const char *fname;
extern int rflags; /* regex flags to use */
@@ -54,5 +53,6 @@ void compile(void);
void cspace(SPACE *, char *, size_t, enum e_spflag);
char *cu_fgets(char *, int, int *);
int mf_fgets(SPACE *, enum e_spflag);
+int lastline(void);
void process(void);
char *strregerror(int, regex_t *);
diff --git a/usr.bin/sed/main.c b/usr.bin/sed/main.c
index e64cfe7..8b97486 100644
--- a/usr.bin/sed/main.c
+++ b/usr.bin/sed/main.c
@@ -96,6 +96,8 @@ struct s_flist {
*/
static struct s_flist *files, **fl_nextp = &files;
+static FILE *curfile; /* Current open file */
+
int aflag, eflag, nflag;
int rflags = 0;
static int rval; /* Exit status */
@@ -107,7 +109,6 @@ static int rval; /* Exit status */
const char *fname; /* File name. */
const char *inplace; /* Inplace edit file extension. */
u_long linenum;
-int lastline; /* TRUE on the last line of the last file */
static void add_compunit(enum e_cut, char *);
static void add_file(char *);
@@ -298,36 +299,34 @@ mf_fgets(sp, spflag)
SPACE *sp;
enum e_spflag spflag;
{
- static FILE *f; /* Current open file */
size_t len;
char *p;
int c;
static int firstfile;
- if (f == NULL) {
+ if (curfile == NULL) {
/* stdin? */
if (files->fname == NULL) {
if (inplace != NULL)
errx(1, "-i may not be used with stdin");
- f = stdin;
+ curfile = stdin;
fname = "stdin";
}
firstfile = 1;
}
for (;;) {
- if (f != NULL && (c = getc(f)) != EOF) {
- (void)ungetc(c, f);
+ if (curfile != NULL && (c = getc(curfile)) != EOF) {
+ (void)ungetc(c, curfile);
break;
}
/* If we are here then either eof or no files are open yet */
- if (f == stdin) {
+ if (curfile == stdin) {
sp->len = 0;
- lastline = 1;
return (0);
}
- if (f != NULL) {
- fclose(f);
+ if (curfile != NULL) {
+ fclose(curfile);
}
if (firstfile == 0) {
files = files->next;
@@ -335,7 +334,6 @@ mf_fgets(sp, spflag)
firstfile = 0;
if (files == NULL) {
sp->len = 0;
- lastline = 1;
return (0);
}
if (inplace != NULL) {
@@ -343,7 +341,7 @@ mf_fgets(sp, spflag)
continue;
}
fname = files->fname;
- if ((f = fopen(fname, "r")) == NULL) {
+ if ((curfile = fopen(fname, "r")) == NULL) {
warn("%s", fname);
rval = 1;
continue;
@@ -352,28 +350,21 @@ mf_fgets(sp, spflag)
unlink(fname);
}
/*
- * We are here only when f is open and we still have something to
- * read from it.
+ * We are here only when curfile is open and we still have something
+ * to read from it.
*
* Use fgetln so that we can handle essentially infinite input data.
* Can't use the pointer into the stdio buffer as the process space
* because the ungetc() can cause it to move.
*/
- p = fgetln(f, &len);
- if (ferror(f))
+ p = fgetln(curfile, &len);
+ if (ferror(curfile))
errx(1, "%s: %s", fname, strerror(errno ? errno : EIO));
if (len != 0 && p[len - 1] == '\n')
len--;
cspace(sp, p, len, spflag);
linenum++;
- if (files->next == NULL) {
- if ((c = getc(f)) != EOF) {
- (void)ungetc(c, f);
- } else {
- lastline = 1;
- }
- }
return (1);
}
@@ -466,3 +457,16 @@ inplace_edit(filename)
*filename = strdup(backup);
return 0;
}
+
+int
+lastline(void)
+{
+ int ch;
+
+ if (files->next != NULL)
+ return (0);
+ if ((ch = getc(curfile)) == EOF)
+ return (1);
+ ungetc(ch, curfile);
+ return (0);
+}
diff --git a/usr.bin/sed/process.c b/usr.bin/sed/process.c
index b2cfbc7..0b24f12 100644
--- a/usr.bin/sed/process.c
+++ b/usr.bin/sed/process.c
@@ -270,7 +270,7 @@ new: if (!nflag && !pd)
*/
#define MATCH(a) \
(a)->type == AT_RE ? regexec_e((a)->u.r, ps, 0, 1, psl) : \
- (a)->type == AT_LINE ? linenum == (a)->u.l : lastline
+ (a)->type == AT_LINE ? linenum == (a)->u.l : lastline()
/*
* Return TRUE if the command applies to the current line. Sets the inrange
OpenPOWER on IntegriCloud