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
This commit is contained in:
Tim J. Robbins 2002-07-03 14:38:27 +00:00
parent 5a3232258e
commit 8523e9a677
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=99352
3 changed files with 29 additions and 25 deletions

View file

@ -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 *);

View file

@ -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);
}

View file

@ -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