From 110c2de07c405176de37d5a49c2173d05a37ae84 Mon Sep 17 00:00:00 2001 From: tjr Date: Wed, 3 Jul 2002 14:38:27 +0000 Subject: 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 --- usr.bin/sed/extern.h | 2 +- usr.bin/sed/main.c | 50 +++++++++++++++++++++++++++----------------------- usr.bin/sed/process.c | 2 +- 3 files changed, 29 insertions(+), 25 deletions(-) (limited to 'usr.bin/sed') 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 -- cgit v1.1