summaryrefslogtreecommitdiff
path: root/inp.c
diff options
context:
space:
mode:
Diffstat (limited to 'inp.c')
-rw-r--r--inp.c672
1 files changed, 402 insertions, 270 deletions
diff --git a/inp.c b/inp.c
index c99054f..7bf497f 100644
--- a/inp.c
+++ b/inp.c
@@ -1,32 +1,64 @@
-/* $Header: inp.c,v 2.0.1.1 88/06/03 15:06:13 lwall Locked $
- *
- * $Log: inp.c,v $
- * Revision 2.0.1.1 88/06/03 15:06:13 lwall
- * patch10: made a little smarter about sccs files
- *
- * Revision 2.0 86/09/17 15:37:02 lwall
- * Baseline for netwide release.
- *
- */
-
-#include "EXTERN.h"
-#include "common.h"
-#include "util.h"
-#include "pch.h"
-#include "INTERN.h"
-#include "inp.h"
+/* inputting files to be patched */
+
+/* $Id: inp.c,v 1.9 1997/04/17 16:15:48 eggert Exp $ */
+
+/*
+Copyright 1986, 1988 Larry Wall
+Copyright 1991, 1992, 1993, 1997 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.
+If not, write to the Free Software Foundation,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#define XTERN extern
+#include <common.h>
+#include <backupfile.h>
+#include <pch.h>
+#include <util.h>
+#undef XTERN
+#define XTERN
+#include <inp.h>
+
+#define SCCSPREFIX "s."
+#define GET "get '%s'"
+#define GET_LOCKED "get -e '%s'"
+#define SCCSDIFF "get -p '%s' | diff - '%s%s' >/dev/null"
+
+#define RCSSUFFIX ",v"
+#define CHECKOUT "co '%s%s'"
+#define CHECKOUT_LOCKED "co -l '%s%s'"
+#define RCSDIFF "rcsdiff '%s%s' > /dev/null"
/* Input-file-with-indexable-lines abstract type */
-static long i_size; /* size of the input file */
-static char *i_womp; /* plan a buffer for entire file */
-static char **i_ptr; /* pointers to lines in i_womp */
+static char const **i_ptr; /* pointers to lines in plan A buffer */
+static size_t tibufsize; /* size of plan b buffers */
+#ifndef TIBUFSIZE_MINIMUM
+#define TIBUFSIZE_MINIMUM (8 * 1024) /* minimum value for tibufsize */
+#endif
static int tifd = -1; /* plan b virtual string array */
static char *tibuf[2]; /* plan b buffers */
static LINENUM tiline[2] = {-1, -1}; /* 1st line in each buffer */
static LINENUM lines_per_buf; /* how many lines per buffer */
-static int tireclen; /* length of records in tmp file */
+static size_t tireclen; /* length of records in tmp file */
+static size_t last_line_size; /* size of last input line */
+
+static bool plan_a PARAMS ((char const *));/* yield FALSE if memory runs out */
+static void plan_b PARAMS ((char const *));
+static void report_revision PARAMS ((int));
/* New patch--prepare to edit another file. */
@@ -34,23 +66,16 @@ void
re_input()
{
if (using_plan_a) {
- i_size = 0;
-#ifndef lint
- if (i_ptr != Null(char**))
- free((char *)i_ptr);
-#endif
- if (i_womp != Nullch)
- free(i_womp);
- i_womp = Nullch;
- i_ptr = Null(char **);
+ if (i_ptr) {
+ free (i_ptr);
+ i_ptr = 0;
+ }
}
else {
- using_plan_a = TRUE; /* maybe the next one is smaller */
- Close(tifd);
+ close (tifd);
tifd = -1;
free(tibuf[0]);
- free(tibuf[1]);
- tibuf[0] = tibuf[1] = Nullch;
+ tibuf[0] = 0;
tiline[0] = tiline[1] = -1;
tireclen = 0;
}
@@ -62,270 +87,393 @@ void
scan_input(filename)
char *filename;
{
- if (!plan_a(filename))
+ using_plan_a = plan_a (filename);
+ if (!using_plan_a)
plan_b(filename);
- if (verbose) {
- say3("Patching file %s using Plan %s...\n", filename,
- (using_plan_a ? "A" : "B") );
+ switch (verbosity)
+ {
+ case SILENT:
+ break;
+
+ case VERBOSE:
+ say ("Patching file %s using Plan %s...\n",
+ filename, using_plan_a ? "A" : "B");
+ break;
+
+ case DEFAULT_VERBOSITY:
+ say ("patching file %s\n", filename);
+ break;
+ }
+}
+
+/* Report whether a desired revision was found. */
+
+static void
+report_revision (found_revision)
+ int found_revision;
+{
+ if (found_revision)
+ {
+ if (verbosity == VERBOSE)
+ say ("Good. This file appears to be the %s version.\n", revision);
+ }
+ else if (force)
+ {
+ if (verbosity != SILENT)
+ say ("Warning: this file doesn't appear to be the %s version--patching anyway.\n",
+ revision);
+ }
+ else if (batch)
+ {
+ fatal ("this file doesn't appear to be the %s version--aborting.",
+ revision);
+ }
+ else
+ {
+ ask ("This file doesn't appear to be the %s version--patch anyway? [n] ",
+ revision);
+ if (*buf != 'y')
+ fatal ("aborted");
}
}
-/* Try keeping everything in memory. */
-bool
-plan_a(filename)
-char *filename;
+void
+get_input_file (filename, outname)
+ char const *filename;
+ char const *outname;
{
- int ifd, statfailed;
- Reg1 char *s;
- Reg2 LINENUM iline;
- char lbuf[MAXLINELEN];
- int output_elsewhere = strcmp(filename, outname);
-
- statfailed = stat(filename, &filestat);
- if (statfailed && ok_to_create_file) {
- if (verbose)
- say2("(Creating file %s...)\n",filename);
- makedirs(filename, TRUE);
- close(creat(filename, 0666));
- statfailed = stat(filename, &filestat);
+ int elsewhere = strcmp (filename, outname);
+ char const *dotslash;
+
+ if (inerrno == -1)
+ inerrno = stat (inname, &instat) == 0 ? 0 : errno;
+ if (inerrno && ok_to_create_file) {
+ int fd;
+ if (verbosity == VERBOSE)
+ say ("(Creating file %s...)\n", inname);
+ if (dry_run) {
+ inerrno = 0;
+ instat.st_mode = 0;
+ instat.st_size = 0;
+ return;
+ }
+ makedirs (inname);
+ fd = creat (inname, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+ if (fd < 0)
+ inerrno = errno;
+ else {
+ inerrno = fstat (fd, &instat) == 0 ? 0 : errno;
+ if (close (fd) != 0)
+ inerrno = errno;
+ }
}
+
/* For nonexistent or read-only files, look for RCS or SCCS versions. */
- if (statfailed
- || (! output_elsewhere
- && (/* No one can write to it. */
- (filestat.st_mode & 0222) == 0
- /* I can't write to it. */
- || ((filestat.st_mode & 0022) == 0
- && filestat.st_uid != myuid)))) {
+ if (backup_type == numbered_existing
+ && (inerrno
+ || (! elsewhere
+ && (/* No one can write to it. */
+ (instat.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) == 0
+ /* I can't write to it. */
+ || ((instat.st_mode & (S_IWGRP|S_IWOTH)) == 0
+ && instat.st_uid != getuid ()))))) {
+ register char *s;
struct stat cstat;
- char *cs = Nullch;
- char *filebase;
- int pathlen;
+ char const *cs = 0;
+ char const *filebase;
+ size_t dir_len;
+ char *lbuf = xmalloc (strlen (filename) + 100);
- filebase = basename(filename);
- pathlen = filebase - filename;
+ strcpy (lbuf, filename);
+ dir_len = base_name (lbuf) - lbuf;
+ filebase = filename + dir_len;
/* Put any leading path into `s'.
Leave room in lbuf for the diff command. */
s = lbuf + 20;
- strncpy(s, filename, pathlen);
+ memcpy (s, filename, dir_len);
+ dotslash = *filename=='-' ? "./" : "";
-#define try(f,a1,a2) (Sprintf(s + pathlen, f, a1, a2), stat(s, &cstat) == 0)
- if (( try("RCS/%s%s", filebase, RCSSUFFIX)
- || try("RCS/%s" , filebase, 0)
- || try( "%s%s", filebase, RCSSUFFIX))
+#define try1(f,a1) (sprintf (s + dir_len, f, a1), stat (s, &cstat) == 0)
+#define try2(f,a1,a2) (sprintf (s + dir_len, f, a1,a2), stat (s, &cstat) == 0)
+ if (( try2 ("RCS/%s%s", filebase, RCSSUFFIX)
+ || try1 ("RCS/%s" , filebase)
+ || try2 ( "%s%s", filebase, RCSSUFFIX))
&&
/* Check that RCS file is not working file.
Some hosts don't report file name length errors. */
- (statfailed
- || ( (filestat.st_dev ^ cstat.st_dev)
- | (filestat.st_ino ^ cstat.st_ino)))) {
- Sprintf(buf, output_elsewhere?CHECKOUT:CHECKOUT_LOCKED, filename);
- Sprintf(lbuf, RCSDIFF, filename);
+ (inerrno
+ || ( (instat.st_dev ^ cstat.st_dev)
+ | (instat.st_ino ^ cstat.st_ino)))) {
+ sprintf (buf, elsewhere ? CHECKOUT : CHECKOUT_LOCKED,
+ dotslash, filename);
+ sprintf (lbuf, RCSDIFF, dotslash, filename);
cs = "RCS";
- } else if ( try("SCCS/%s%s", SCCSPREFIX, filebase)
- || try( "%s%s", SCCSPREFIX, filebase)) {
- Sprintf(buf, output_elsewhere?GET:GET_LOCKED, s);
- Sprintf(lbuf, SCCSDIFF, s, filename);
+ } else if ( try2 ("SCCS/%s%s", SCCSPREFIX, filebase)
+ || try2 ( "%s%s", SCCSPREFIX, filebase)) {
+ sprintf (buf, elsewhere ? GET : GET_LOCKED, s);
+ sprintf (lbuf, SCCSDIFF, s, dotslash, filename);
cs = "SCCS";
- } else if (statfailed)
- fatal2("can't find %s\n", filename);
+ } else if (inerrno)
+ fatal ("can't find %s", filename);
/* else we can't write to it but it's not under a version
control system, so just proceed. */
if (cs) {
- if (!statfailed) {
- if ((filestat.st_mode & 0222) != 0)
+ if (!inerrno) {
+ if ((instat.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) != 0)
/* The owner can write to it. */
- fatal3("file %s seems to be locked by somebody else under %s\n",
+ fatal ("file %s seems to be locked by somebody else under %s",
filename, cs);
/* It might be checked out unlocked. See if it's safe to
check out the default version locked. */
- if (verbose)
- say3("Comparing file %s to default %s version...\n",
+ if (verbosity == VERBOSE)
+ say ("Comparing file %s to default %s version...\n",
filename, cs);
- if (system(lbuf))
- fatal3("can't check out file %s: differs from default %s version\n",
- filename, cs);
+ if (system (lbuf) != 0)
+ {
+ say ("warning: patching file %s, which does not match default %s version\n",
+ filename, cs);
+ cs = 0;
+ }
}
- if (verbose)
- say3("Checking out file %s from %s...\n", filename, cs);
- if (system(buf) || stat(filename, &filestat))
- fatal3("can't check out file %s from %s\n", filename, cs);
+ if (cs)
+ {
+ if (dry_run)
+ {
+ if (inerrno)
+ fatal ("Cannot dry run on nonexistent version-controlled file `%s'; invoke `%s' and try again.",
+ filename, buf);
+ }
+ else
+ {
+ if (verbosity == VERBOSE)
+ say ("Checking out file %s from %s...\n", filename, cs);
+ if (system (buf) != 0 || stat (filename, &instat) != 0)
+ fatal ("can't check out file %s from %s", filename, cs);
+ inerrno = 0;
+ }
+ }
}
+ free (lbuf);
}
- filemode = filestat.st_mode;
- if (!S_ISREG(filemode))
- fatal2("%s is not a normal file--can't patch\n", filename);
- i_size = filestat.st_size;
- if (out_of_mem) {
- set_hunkmax(); /* make sure dynamic arrays are allocated */
- out_of_mem = FALSE;
- return FALSE; /* force plan b because plan a bombed */
- }
-#ifdef lint
- i_womp = Nullch;
-#else
- i_womp = malloc((MEM)(i_size+2)); /* lint says this may alloc less than */
- /* i_size, but that's okay, I think. */
-#endif
- if (i_womp == Nullch)
- return FALSE;
- if ((ifd = open(filename, 0)) < 0)
- pfatal2("can't open file %s", filename);
-#ifndef lint
- if (read(ifd, i_womp, (int)i_size) != i_size) {
- Close(ifd); /* probably means i_size > 15 or 16 bits worth */
- free(i_womp); /* at this point it doesn't matter if i_womp was */
- return FALSE; /* undersized. */
- }
-#endif
- Close(ifd);
- if (i_size && i_womp[i_size-1] != '\n')
- i_womp[i_size++] = '\n';
- i_womp[i_size] = '\0';
+ if (!S_ISREG (instat.st_mode))
+ fatal ("%s is not a regular file--can't patch", filename);
+}
- /* count the lines in the buffer so we know how many pointers we need */
- iline = 0;
- for (s=i_womp; *s; s++) {
- if (*s == '\n')
- iline++;
- }
-#ifdef lint
- i_ptr = Null(char**);
-#else
- i_ptr = (char **)malloc((MEM)((iline + 2) * sizeof(char *)));
-#endif
- if (i_ptr == Null(char **)) { /* shucks, it was a near thing */
- free((char *)i_womp);
- return FALSE;
+/* Try keeping everything in memory. */
+
+static bool
+plan_a(filename)
+ char const *filename;
+{
+ register char const *s;
+ register char const *lim;
+ register char const **ptr;
+ register char *buffer;
+ register LINENUM iline;
+ size_t size = instat.st_size;
+ size_t allocated_bytes_per_input_byte = sizeof *i_ptr + sizeof (char);
+ size_t allocated_bytes = (size + 2) * allocated_bytes_per_input_byte;
+
+ /* Fail if arithmetic overflow occurs during size calculations,
+ or if storage isn't available. */
+ if (size != instat.st_size
+ || size + 2 < 2
+ || allocated_bytes / allocated_bytes_per_input_byte != size + 2
+ || ! (ptr = (char const **) malloc (allocated_bytes)))
+ return FALSE;
+
+ buffer = (char *) (ptr + (size + 2));
+
+ /* Read the input file, but don't bother reading it if it's empty.
+ During dry runs, empty files may not actually exist. */
+ if (size)
+ {
+ int ifd = open (filename, O_RDONLY);
+ if (ifd < 0)
+ pfatal ("can't open file %s", filename);
+ if (read (ifd, buffer, size) != size)
+ {
+ /* Perhaps size is too large for this host. */
+ close (ifd);
+ free (ptr);
+ return FALSE;
+ }
+ if (close (ifd) != 0)
+ read_fatal ();
}
-
- /* now scan the buffer and build pointer array */
-
- iline = 1;
- i_ptr[iline] = i_womp;
- for (s=i_womp; *s; s++) {
- if (*s == '\n')
- i_ptr[++iline] = s+1; /* these are NOT null terminated */
+
+ /* Scan the buffer and build array of pointers to lines. */
+ iline = 0;
+ lim = buffer + size;
+ for (s = buffer; ; s++)
+ {
+ ptr[++iline] = s;
+ if (! (s = (char *) memchr (s, '\n', lim - s)))
+ break;
}
- input_lines = iline - 1;
+ if (size && lim[-1] != '\n')
+ ptr[++iline] = lim;
+ input_lines = iline - 1;
- /* now check for revision, if any */
+ if (revision)
+ {
+ char const *rev = revision;
+ int rev0 = rev[0];
+ int found_revision = 0;
+ size_t revlen = strlen (rev);
- if (revision != Nullch) {
- if (!rev_in_string(i_womp)) {
- if (force) {
- if (verbose)
- say2(
-"Warning: this file doesn't appear to be the %s version--patching anyway.\n",
- revision);
- }
- else if (batch) {
- fatal2(
-"this file doesn't appear to be the %s version--aborting.\n", revision);
- }
- else {
- ask2(
-"This file doesn't appear to be the %s version--patch anyway? [n] ",
- revision);
- if (*buf != 'y')
- fatal1("aborted\n");
- }
+ if (revlen <= size)
+ {
+ char const *limrev = lim - revlen;
+
+ for (s = buffer; (s = (char *) memchr (s, rev0, limrev - s)); s++)
+ if (memcmp (s, rev, revlen) == 0
+ && (s == buffer || ISSPACE ((unsigned char) s[-1]))
+ && (s + 1 == limrev || ISSPACE ((unsigned char) s[revlen])))
+ {
+ found_revision = 1;
+ break;
+ }
}
- else if (verbose)
- say2("Good. This file appears to be the %s version.\n",
- revision);
+
+ report_revision (found_revision);
}
- return TRUE; /* plan a will work */
+
+ /* Plan A will work. */
+ i_ptr = ptr;
+ return TRUE;
}
/* Keep (virtually) nothing in memory. */
-void
+static void
plan_b(filename)
-char *filename;
+ char const *filename;
{
- Reg3 FILE *ifp;
- Reg1 int i = 0;
- Reg2 int maxlen = 1;
- Reg4 bool found_revision = (revision == Nullch);
-
- using_plan_a = FALSE;
- if ((ifp = fopen(filename, "r")) == Nullfp)
- pfatal2("can't open file %s", filename);
- if ((tifd = creat(TMPINNAME, 0666)) < 0)
- pfatal2("can't open file %s", TMPINNAME);
- while (fgets(buf, sizeof buf, ifp) != Nullch) {
- if (revision != Nullch && !found_revision && rev_in_string(buf))
- found_revision = TRUE;
- if ((i = strlen(buf)) > maxlen)
- maxlen = i; /* find longest line */
- }
- if (revision != Nullch) {
- if (!found_revision) {
- if (force) {
- if (verbose)
- say2(
-"Warning: this file doesn't appear to be the %s version--patching anyway.\n",
- revision);
- }
- else if (batch) {
- fatal2(
-"this file doesn't appear to be the %s version--aborting.\n", revision);
- }
- else {
- ask2(
-"This file doesn't appear to be the %s version--patch anyway? [n] ",
- revision);
- if (*buf != 'y')
- fatal1("aborted\n");
+ register FILE *ifp;
+ register int c;
+ register size_t len;
+ register size_t maxlen;
+ register int found_revision;
+ register size_t i;
+ register char const *rev;
+ register size_t revlen;
+ register LINENUM line;
+
+ if (dry_run)
+ filename = "/dev/null";
+ if (! (ifp = fopen (filename, "r")))
+ pfatal ("can't open file %s", filename);
+ tifd = creat (TMPINNAME, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+ if (tifd < 0)
+ pfatal ("can't open file %s", TMPINNAME);
+ i = 0;
+ len = 0;
+ maxlen = 1;
+ rev = revision;
+ found_revision = !rev;
+ revlen = rev ? strlen (rev) : 0;
+
+ while ((c = getc (ifp)) != EOF)
+ {
+ len++;
+
+ if (c == '\n')
+ {
+ if (maxlen < len)
+ maxlen = len;
+ len = 0;
+ }
+
+ if (!found_revision)
+ {
+ if (i == revlen)
+ {
+ found_revision = ISSPACE ((unsigned char) c);
+ i = (size_t) -1;
}
+ else if (i != (size_t) -1)
+ i = rev[i]==c ? i + 1 : (size_t) -1;
+
+ if (i == (size_t) -1 && ISSPACE ((unsigned char) c))
+ i = 0;
}
- else if (verbose)
- say2("Good. This file appears to be the %s version.\n",
- revision);
}
- Fseek(ifp, 0L, 0); /* rewind file */
- lines_per_buf = BUFFERSIZE / maxlen;
- tireclen = maxlen;
- tibuf[0] = malloc((MEM)(BUFFERSIZE + 1));
- tibuf[1] = malloc((MEM)(BUFFERSIZE + 1));
- if (tibuf[1] == Nullch)
- fatal1("out of memory\n");
- for (i=1; ; i++) {
- if (! (i % lines_per_buf)) /* new block */
- if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
- pfatal1("can't write temp file");
- if (fgets(tibuf[0] + maxlen * (i%lines_per_buf), maxlen + 1, ifp)
- == Nullch) {
- input_lines = i - 1;
- if (i % lines_per_buf)
- if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
- pfatal1("can't write temp file");
- break;
+
+ if (revision)
+ report_revision (found_revision);
+ Fseek (ifp, (off_t) 0, SEEK_SET); /* rewind file */
+ for (tibufsize = TIBUFSIZE_MINIMUM; tibufsize < maxlen; tibufsize <<= 1)
+ continue;
+ lines_per_buf = tibufsize / maxlen;
+ tireclen = maxlen;
+ tibuf[0] = xmalloc (2 * tibufsize);
+ tibuf[1] = tibuf[0] + tibufsize;
+
+ for (line = 1; ; line++)
+ {
+ char *p = tibuf[0] + maxlen * (line % lines_per_buf);
+ char const *p0 = p;
+ if (! (line % lines_per_buf)) /* new block */
+ if (write (tifd, tibuf[0], tibufsize) != tibufsize)
+ write_fatal ();
+ if ((c = getc (ifp)) == EOF)
+ break;
+
+ for (;;)
+ {
+ *p++ = c;
+ if (c == '\n')
+ {
+ last_line_size = p - p0;
+ break;
+ }
+
+ if ((c = getc (ifp)) == EOF)
+ {
+ last_line_size = p - p0;
+ line++;
+ goto EOF_reached;
+ }
}
}
- Fclose(ifp);
- Close(tifd);
- if ((tifd = open(TMPINNAME, 0)) < 0) {
- pfatal2("can't reopen file %s", TMPINNAME);
- }
+ EOF_reached:
+ if (ferror (ifp) || fclose (ifp) != 0)
+ read_fatal ();
+
+ if (line % lines_per_buf != 0)
+ if (write (tifd, tibuf[0], tibufsize) != tibufsize)
+ write_fatal ();
+ input_lines = line - 1;
+ if (close (tifd) != 0)
+ write_fatal ();
+ if ((tifd = open (TMPINNAME, O_RDONLY)) < 0)
+ pfatal ("can't reopen file %s", TMPINNAME);
}
-/* Fetch a line from the input file, \n terminated, not necessarily \0. */
+/* Fetch a line from the input file. */
-char *
-ifetch(line,whichbuf)
-Reg1 LINENUM line;
+char const *
+ifetch (line, whichbuf, psize)
+register LINENUM line;
int whichbuf; /* ignored when file in memory */
+size_t *psize;
{
- if (line < 1 || line > input_lines)
+ register char const *q;
+ register char const *p;
+
+ if (line < 1 || line > input_lines) {
+ *psize = 0;
return "";
- if (using_plan_a)
- return i_ptr[line];
- else {
+ }
+ if (using_plan_a) {
+ p = i_ptr[line];
+ *psize = i_ptr[line + 1] - p;
+ return p;
+ } else {
LINENUM offline = line % lines_per_buf;
LINENUM baseline = line - offline;
@@ -335,35 +483,19 @@ int whichbuf; /* ignored when file in memory */
whichbuf = 1;
else {
tiline[whichbuf] = baseline;
-#ifndef lint /* complains of long accuracy */
- Lseek(tifd, (long)baseline / lines_per_buf * BUFFERSIZE, 0);
-#endif
- if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0)
- pfatal2("error reading tmp file %s", TMPINNAME);
+ if (lseek (tifd, (off_t) (baseline/lines_per_buf * tibufsize),
+ SEEK_SET) == -1
+ || read (tifd, tibuf[whichbuf], tibufsize) < 0)
+ read_fatal ();
}
- return tibuf[whichbuf] + (tireclen*offline);
- }
-}
-
-/* True if the string argument contains the revision number we want. */
-
-bool
-rev_in_string(string)
-char *string;
-{
- Reg1 char *s;
- Reg2 int patlen;
-
- if (revision == Nullch)
- return TRUE;
- patlen = strlen(revision);
- if (strnEQ(string,revision,patlen) && isspace(string[patlen]))
- return TRUE;
- for (s = string; *s; s++) {
- if (isspace(*s) && strnEQ(s+1, revision, patlen) &&
- isspace(s[patlen+1] )) {
- return TRUE;
+ p = tibuf[whichbuf] + (tireclen*offline);
+ if (line == input_lines)
+ *psize = last_line_size;
+ else {
+ for (q = p; *q++ != '\n'; )
+ continue;
+ *psize = q - p;
}
+ return p;
}
- return FALSE;
}