mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 17:18:32 +00:00
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:
parent
5a3232258e
commit
8523e9a677
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=99352
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue