summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/rcs/lib/rcslex.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/rcs/lib/rcslex.c')
-rw-r--r--gnu/usr.bin/rcs/lib/rcslex.c829
1 files changed, 572 insertions, 257 deletions
diff --git a/gnu/usr.bin/rcs/lib/rcslex.c b/gnu/usr.bin/rcs/lib/rcslex.c
index 621d492..09d41cb 100644
--- a/gnu/usr.bin/rcs/lib/rcslex.c
+++ b/gnu/usr.bin/rcs/lib/rcslex.c
@@ -1,17 +1,16 @@
-/*
- * RCS file input
- */
-/*********************************************************************************
+/* lexical analysis of RCS files */
+
+/******************************************************************************
* Lexical Analysis.
* hashtable, Lexinit, nextlex, getlex, getkey,
* getid, getnum, readstring, printstring, savestring,
* checkid, fatserror, error, faterror, warn, diagnose
* Testprogram: define LEXDB
- *********************************************************************************
+ ******************************************************************************
*/
-/* Copyright (C) 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991 by Paul Eggert
+/* Copyright 1982, 1988, 1989 Walter Tichy
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
Distributed under license by the Free Software Foundation, Inc.
This file is part of RCS.
@@ -27,8 +26,9 @@ 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 RCS; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+along with RCS; see the file COPYING.
+If not, write to the Free Software Foundation,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Report problems and direct all questions to:
@@ -38,13 +38,43 @@ Report problems and direct all questions to:
-/* $Log: rcslex.c,v $
- * Revision 1.2 1993/06/28 19:13:10 nate
- * Added Chris Demetriou's FSYNC_ALL option which causes all writes to be
- * flushed immediately. (In case of a crash in the middle of CVS/RCS commits
+/*
+ * $Log: rcslex.c,v $
+ * Revision 5.19 1995/06/16 06:19:24 eggert
+ * Update FSF address.
+ *
+ * Revision 5.18 1995/06/01 16:23:43 eggert
+ * (map_fd_deallocate,mmap_deallocate,read_deallocate,nothing_to_deallocate):
+ * New functions.
+ * (Iclose): If large_memory and maps_memory, use them to deallocate mapping.
+ * (fd2RILE): Use map_fd if available.
+ * If one mapping method fails, try the next instead of giving up;
+ * if they all fail, fall back on ordinary read.
+ * Work around bug: root mmap over NFS succeeds, but accessing dumps core.
+ * Use MAP_FAILED macro for mmap failure, and `char *' instead of caddr_t.
+ * (advise_access): Use madvise only if this instance used mmap.
+ * (Iopen): Use fdSafer to get safer file descriptor.
+ * (aflush): Moved here from rcsedit.c.
+ *
+ * Revision 5.17 1994/03/20 04:52:58 eggert
+ * Don't worry if madvise fails. Add Orewind. Remove lint.
+ *
+ * Revision 5.16 1993/11/09 17:55:29 eggert
+ * Fix `label: }' typo.
*
- * Revision 1.1.1.1 1993/06/18 04:22:12 jkh
- * Updated GNU utilities
+ * Revision 5.15 1993/11/03 17:42:27 eggert
+ * Improve quality of diagnostics by putting file names in them more often.
+ * Don't discard ignored phrases.
+ *
+ * Revision 5.14 1992/07/28 16:12:44 eggert
+ * Identifiers may now start with a digit and (unless they are symbolic names)
+ * may contain `.'. Avoid `unsigned'. Statement macro names now end in _.
+ *
+ * Revision 5.13 1992/02/17 23:02:27 eggert
+ * Work around NFS mmap SIGBUS problem.
+ *
+ * Revision 5.12 1992/01/06 02:42:34 eggert
+ * Use OPEN_O_BINARY if mode contains 'b'.
*
* Revision 5.11 1991/11/03 03:30:44 eggert
* Fix porting bug to ancient hosts lacking vfprintf.
@@ -139,7 +169,14 @@ Report problems and direct all questions to:
#include "rcsbase.h"
-libId(lexId, "$Id: rcslex.c,v 1.2 1993/06/28 19:13:10 nate Exp $")
+libId(lexId, "$Id: rcslex.c,v 5.19 1995/06/16 06:19:24 eggert Exp $")
+
+static char *checkidentifier P((char*,int,int));
+static void errsay P((char const*));
+static void fatsay P((char const*));
+static void lookup P((char const*));
+static void startsay P((const char*,const char*));
+static void warnsay P((char const*));
static struct hshentry *nexthsh; /*pointer to next hash entry, set by lookup*/
@@ -149,7 +186,7 @@ int hshenter; /*if true, next suitable lexeme will be entered */
/*into the symbol table. Handle with care. */
int nextc; /*next input character, initialized by Lexinit */
-unsigned long rcsline; /*current line-number of input */
+long rcsline; /*current line-number of input */
int nerror; /*counter for errors */
int quietflag; /*indicates quiet mode */
RILE * finptr; /*input file descriptor */
@@ -179,9 +216,9 @@ static int ignored_phrases; /* have we ignored phrases in this RCS file? */
void
warnignore()
{
- if (! (ignored_phrases|quietflag)) {
+ if (!ignored_phrases) {
ignored_phrases = true;
- warn("Unknown phrases like `%s ...;' are in the RCS file.", NextString);
+ rcswarn("Unknown phrases like `%s ...;' are present.", NextString);
}
}
@@ -212,7 +249,7 @@ lookup(str)
/* empty slot found */
*p = n = ftalloc(struct hshentry);
n->num = fstr_save(str);
- n->nexthsh = nil;
+ n->nexthsh = 0;
# ifdef LEXDB
VOID printf("\nEntered: %s at %u ", str, ihash);
# endif
@@ -238,7 +275,7 @@ Lexinit()
{ register int c;
for (c = hshsize; 0 <= --c; ) {
- hshtab[c] = nil;
+ hshtab[c] = 0;
}
nerror = 0;
@@ -248,7 +285,7 @@ Lexinit()
ignored_phrases = false;
rcsline = 1;
bufrealloc(&tokbuf, 2);
- Iget(finptr, nextc);
+ Iget_(finptr, nextc)
nextlex(); /*initial token*/
}
}
@@ -295,46 +332,48 @@ nextlex()
/* Note: falls into next case */
case SPACE:
- GETC(frew, c);
+ GETC_(frew, c)
continue;
- case DIGIT:
- sp = tokbuf.string;
- limit = sp + tokbuf.size;
- *sp++ = c;
- for (;;) {
- GETC(frew, c);
- if ((d=ctab[c])!=DIGIT && d!=PERIOD)
- break;
- *sp++ = c; /* 1.2. and 1.2 are different */
- if (limit <= sp)
- sp = bufenlarge(&tokbuf, &limit);
- }
- *sp = 0;
- if (hshenter)
- lookup(tokbuf.string);
- else
- NextString = fstr_save(tokbuf.string);
- d = NUM;
- break;
-
-
- case LETTER:
+ case IDCHAR:
+ case LETTER:
case Letter:
+ d = ID;
+ /* fall into */
+ case DIGIT:
+ case PERIOD:
sp = tokbuf.string;
limit = sp + tokbuf.size;
*sp++ = c;
for (;;) {
- GETC(frew, c);
- if ((d=ctab[c])!=LETTER && d!=Letter && d!=DIGIT && d!=IDCHAR)
+ GETC_(frew, c)
+ switch (ctab[c]) {
+ case IDCHAR:
+ case LETTER:
+ case Letter:
+ d = ID;
+ /* fall into */
+ case DIGIT:
+ case PERIOD:
+ *sp++ = c;
+ if (limit <= sp)
+ sp = bufenlarge(&tokbuf, &limit);
+ continue;
+
+ default:
break;
- *sp++ = c;
- if (limit <= sp)
- sp = bufenlarge(&tokbuf, &limit);
+ }
+ break;
}
*sp = 0;
+ if (d == DIGIT || d == PERIOD) {
+ d = NUM;
+ if (hshenter) {
+ lookup(tokbuf.string);
+ break;
+ }
+ }
NextString = fstr_save(tokbuf.string);
- d = ID; /* may be ID or keyword */
break;
case SBEGIN: /* long string */
@@ -345,7 +384,7 @@ nextlex()
case COLON:
case SEMI:
- GETC(frew, c);
+ GETC_(frew, c)
break;
} break; }
nextc = c;
@@ -381,11 +420,11 @@ eoflex()
++rcsline;
/* fall into */
case SPACE:
- cachegeteof(c, {uncache(fin);return true;});
+ cachegeteof_(c, {uncache(fin);return true;})
break;
}
if (fout)
- aputc(c, fout);
+ aputc_(c, fout)
}
}
@@ -449,7 +488,7 @@ getkeystring(key)
getid()
/* Function: Checks if nexttok is an identifier. If so,
* advances the input by calling nextlex and returns a pointer
- * to the identifier; otherwise returns nil.
+ * to the identifier; otherwise returns 0.
* Treats keywords as identifiers.
*/
{
@@ -458,14 +497,15 @@ getid()
name = NextString;
nextlex();
return name;
- } else return nil;
+ } else
+ return 0;
}
struct hshentry * getnum()
/* Function: Checks if nexttok is a number. If so,
* advances the input by calling nextlex and returns a pointer
- * to the hashtable entry. Otherwise returns nil.
+ * to the hashtable entry. Otherwise returns 0.
* Doesn't work if hshenter is false.
*/
{
@@ -474,46 +514,55 @@ struct hshentry * getnum()
num=nexthsh;
nextlex();
return num;
- } else return nil;
+ } else
+ return 0;
}
struct cbuf
getphrases(key)
char const *key;
-/* Get a series of phrases that do not start with KEY, yield resulting buffer.
- * Stop when the next phrase starts with a token that is not an identifier,
- * or is KEY.
- * Assume !foutptr.
- */
+/*
+* Get a series of phrases that do not start with KEY. Yield resulting buffer.
+* Stop when the next phrase starts with a token that is not an identifier,
+* or is KEY. Copy input to foutptr if it is set. Unlike ignorephrases(),
+* this routine assumes nextlex() has already been invoked before we start.
+*/
{
declarecache;
register int c;
- register char *p;
- char const *limit;
- register char const *ki, *kn;
+ register char const *kn;
struct cbuf r;
- struct buf b;
register RILE *fin;
+ register FILE *frew;
+# if large_memory
+# define savech_(c) ;
+# else
+ register char *p;
+ char const *limit;
+ struct buf b;
+# define savech_(c) {if (limit<=p)p=bufenlarge(&b,&limit); *p++ =(c);}
+# endif
- if (nexttok!=ID || strcmp(NextString,key) == 0) {
- r.string = 0;
- r.size = 0;
- return r;
- } else {
+ if (nexttok!=ID || strcmp(NextString,key) == 0)
+ clear_buf(&r);
+ else {
warnignore();
fin = finptr;
+ frew = foutptr;
setupcache(fin); cache(fin);
- bufautobegin(&b);
- bufscpy(&b, NextString);
+# if large_memory
+ r.string = (char const*)cacheptr() - strlen(NextString) - 1;
+# else
+ bufautobegin(&b);
+ bufscpy(&b, NextString);
+ p = b.string + strlen(b.string);
+ limit = b.string + b.size;
+# endif
ffree1(NextString);
- p = b.string + strlen(b.string);
- limit = b.string + b.size;
c = nextc;
for (;;) {
for (;;) {
- if (limit <= p)
- p = bufenlarge(&b, &limit);
- *p++ = c;
+ savech_(c)
switch (ctab[c]) {
default:
fatserror("unknown character `%c'", c);
@@ -523,15 +572,13 @@ getphrases(key)
/* fall into */
case COLON: case DIGIT: case LETTER: case Letter:
case PERIOD: case SPACE:
- cacheget(c);
+ GETC_(frew, c)
continue;
case SBEGIN: /* long string */
for (;;) {
for (;;) {
- if (limit <= p)
- p = bufenlarge(&b, &limit);
- cacheget(c);
- *p++ = c;
+ GETC_(frew, c)
+ savech_(c)
switch (c) {
case '\n':
++rcsline;
@@ -544,48 +591,50 @@ getphrases(key)
}
break;
}
- cacheget(c);
+ GETC_(frew, c)
if (c != SDELIM)
break;
- if (limit <= p)
- p = bufenlarge(&b, &limit);
- *p++ = c;
+ savech_(c)
}
continue;
case SEMI:
- cacheget(c);
+ cacheget_(c)
if (ctab[c] == NEWLN) {
+ if (frew)
+ aputc_(c, frew)
++rcsline;
- if (limit <= p)
- p = bufenlarge(&b, &limit);
- *p++ = c;
- cacheget(c);
+ savech_(c)
+ cacheget_(c)
}
+# if large_memory
+ r.size = (char const*)cacheptr() - 1 - r.string;
+# endif
for (;;) {
switch (ctab[c]) {
case NEWLN:
++rcsline;
/* fall into */
case SPACE:
- cacheget(c);
+ cacheget_(c)
continue;
default: break;
}
break;
}
+ if (frew)
+ aputc_(c, frew)
break;
}
break;
}
- switch (ctab[c]) {
- case LETTER:
- case Letter:
+ if (ctab[c] == Letter) {
for (kn = key; c && *kn==c; kn++)
- cacheget(c);
+ GETC_(frew, c)
if (!*kn)
switch (ctab[c]) {
case DIGIT: case LETTER: case Letter:
+ case IDCHAR: case PERIOD:
break;
default:
nextc = c;
@@ -594,23 +643,26 @@ getphrases(key)
uncache(fin);
goto returnit;
}
- for (ki=key; ki<kn; ) {
- if (limit <= p)
- p = bufenlarge(&b, &limit);
- *p++ = *ki++;
- }
- break;
-
- default:
+# if !large_memory
+ {
+ register char const *ki;
+ for (ki=key; ki<kn; )
+ savech_(*ki++)
+ }
+# endif
+ } else {
nextc = c;
uncache(fin);
nextlex();
- goto returnit;
+ break;
}
}
- returnit:
- return bufremember(&b, (size_t)(p - b.string));
+ returnit:;
+# if !large_memory
+ return bufremember(&b, (size_t)(p - b.string));
+# endif
}
+ return r;
}
@@ -626,14 +678,14 @@ readstring()
fin=finptr; frew=foutptr;
setupcache(fin); cache(fin);
for (;;) {
- GETC(frew, c);
+ GETC_(frew, c)
switch (c) {
case '\n':
++rcsline;
break;
case SDELIM:
- GETC(frew, c);
+ GETC_(frew, c)
if (c != SDELIM) {
/* end of string */
nextc = c;
@@ -660,13 +712,13 @@ printstring()
fout = stdout;
setupcache(fin); cache(fin);
for (;;) {
- cacheget(c);
+ cacheget_(c)
switch (c) {
case '\n':
++rcsline;
break;
case SDELIM:
- cacheget(c);
+ cacheget_(c)
if (c != SDELIM) {
nextc=c;
uncache(fin);
@@ -674,7 +726,7 @@ printstring()
}
break;
}
- aputc(c,fout);
+ aputc_(c,fout)
}
}
@@ -702,13 +754,13 @@ savestring(target)
setupcache(fin); cache(fin);
tp = target->string; limit = tp + target->size;
for (;;) {
- GETC(frew, c);
+ GETC_(frew, c)
switch (c) {
case '\n':
++rcsline;
break;
case SDELIM:
- GETC(frew, c);
+ GETC_(frew, c)
if (c != SDELIM) {
/* end of string */
nextc=c;
@@ -726,44 +778,76 @@ savestring(target)
}
- char *
-checkid(id, delimiter)
+ static char *
+checkidentifier(id, delimiter, dotok)
register char *id;
int delimiter;
+ register int dotok;
/* Function: check whether the string starting at id is an */
/* identifier and return a pointer to the delimiter*/
/* after the identifier. White space, delim and 0 */
/* are legal delimiters. Aborts the program if not*/
/* a legal identifier. Useful for checking commands*/
/* If !delim, the only delimiter is 0. */
+/* Allow '.' in identifier only if DOTOK is set. */
{
- register enum tokens d;
register char *temp;
- register char c,tc;
+ register char c;
register char delim = delimiter;
+ int isid = false;
temp = id;
- if ((d = ctab[(unsigned char)(c = *id)])==LETTER || d==Letter) {
- while ((d = ctab[(unsigned char)(c = *++id)])==LETTER
- || d==Letter || d==DIGIT || d==IDCHAR
- )
- ;
- if (c && (!delim || c!=delim && c!=' ' && c!='\t' && c!='\n')) {
+ for (;; id++) {
+ switch (ctab[(unsigned char)(c = *id)]) {
+ case IDCHAR:
+ case LETTER:
+ case Letter:
+ isid = true;
+ continue;
+
+ case DIGIT:
+ continue;
+
+ case PERIOD:
+ if (dotok)
+ continue;
+ break;
+
+ default:
+ break;
+ }
+ break;
+ }
+ if ( ! isid
+ || (c && (!delim || (c!=delim && c!=' ' && c!='\t' && c!='\n')))
+ ) {
/* append \0 to end of id before error message */
- tc = c;
- while( (c=(*++id))!=' ' && c!='\t' && c!='\n' && c!='\0' && c!=delim) ;
+ while ((c = *id) && c!=' ' && c!='\t' && c!='\n' && c!=delim)
+ id++;
*id = '\0';
- faterror("invalid character %c in identifier `%s'",tc,temp);
- }
- } else {
- /* append \0 to end of id before error message */
- while( (c=(*++id))!=' ' && c!='\t' && c!='\n' && c!='\0' && c!=delim) ;
- *id = '\0';
- faterror("identifier `%s' doesn't start with letter", temp);
- }
+ faterror("invalid %s `%s'",
+ dotok ? "identifier" : "symbol", temp
+ );
+ }
return id;
}
+ char *
+checkid(id, delimiter)
+ char *id;
+ int delimiter;
+{
+ return checkidentifier(id, delimiter, true);
+}
+
+ char *
+checksym(sym, delimiter)
+ char *sym;
+ int delimiter;
+{
+ return checkidentifier(sym, delimiter, false);
+}
+
void
checksid(id)
char *id;
@@ -772,16 +856,92 @@ checksid(id)
VOID checkid(id, 0);
}
+ void
+checkssym(sym)
+ char *sym;
+{
+ VOID checksym(sym, 0);
+}
+
+
+#if !large_memory
+# define Iclose(f) fclose(f)
+#else
+# if !maps_memory
+ static int Iclose P((RILE *));
+ static int
+ Iclose(f)
+ register RILE *f;
+ {
+ tfree(f->base);
+ f->base = 0;
+ return fclose(f->stream);
+ }
+# else
+ static int Iclose P((RILE *));
+ static int
+ Iclose(f)
+ register RILE *f;
+ {
+ (* f->deallocate) (f);
+ f->base = 0;
+ return close(f->fd);
+ }
+
+# if has_map_fd
+ static void map_fd_deallocate P((RILE *));
+ static void
+ map_fd_deallocate(f)
+ register RILE *f;
+ {
+ if (vm_deallocate(
+ task_self(),
+ (vm_address_t) f->base,
+ (vm_size_t) (f->lim - f->base)
+ ) != KERN_SUCCESS)
+ efaterror("vm_deallocate");
+ }
+# endif
+# if has_mmap
+ static void mmap_deallocate P((RILE *));
+ static void
+ mmap_deallocate(f)
+ register RILE *f;
+ {
+ if (munmap((char *) f->base, (size_t) (f->lim - f->base)) != 0)
+ efaterror("munmap");
+ }
+# endif
+ static void read_deallocate P((RILE *));
+ static void
+ read_deallocate(f)
+ RILE *f;
+ {
+ tfree(f->base);
+ }
+
+ static void nothing_to_deallocate P((RILE *));
+ static void
+ nothing_to_deallocate(f)
+ RILE *f;
+ {
+ }
+# endif
+#endif
+
+#if large_memory && maps_memory
+ static RILE *fd2_RILE P((int,char const*,struct stat*));
static RILE *
-#if has_mmap && large_memory
-fd2_RILE(fd, filename, status)
+fd2_RILE(fd, name, status)
#else
-fd2RILE(fd, filename, mode, status)
- char const *mode;
+ static RILE *fd2RILE P((int,char const*,char const*,struct stat*));
+ static RILE *
+fd2RILE(fd, name, type, status)
+ char const *type;
#endif
int fd;
- char const *filename;
+ char const *name;
register struct stat *status;
{
struct stat st;
@@ -789,67 +949,127 @@ fd2RILE(fd, filename, mode, status)
if (!status)
status = &st;
if (fstat(fd, status) != 0)
- efaterror(filename);
+ efaterror(name);
if (!S_ISREG(status->st_mode)) {
- error("`%s' is not a regular file", filename);
+ error("`%s' is not a regular file", name);
VOID close(fd);
errno = EINVAL;
return 0;
} else {
-# if ! (has_mmap && large_memory)
+# if !(large_memory && maps_memory)
FILE *stream;
- if (!(stream = fdopen(fd, mode)))
- efaterror(filename);
+ if (!(stream = fdopen(fd, type)))
+ efaterror(name);
# endif
# if !large_memory
return stream;
# else
# define RILES 3
- {
- static RILE rilebuf[RILES];
-
- register RILE *f;
- size_t s = status->st_size;
-
- if (s != status->st_size)
- faterror("`%s' is enormous", filename);
- for (f = rilebuf; f->base; f++)
- if (f == rilebuf+RILES)
- faterror("too many RILEs");
- if (!s) {
- static unsigned char dummy;
- f->base = &dummy;
- } else {
-# if has_mmap
- if (
- (f->base = (unsigned char *)mmap(
- (caddr_t)0, s, PROT_READ, MAP_SHARED,
- fd, (off_t)0
- )) == (unsigned char *)-1
- )
- efaterror("mmap");
-# else
- f->base = tnalloc(unsigned char, s);
+ {
+ static RILE rilebuf[RILES];
+
+ register RILE *f;
+ size_t s = status->st_size;
+
+ if (s != status->st_size)
+ faterror("%s: too large", name);
+ for (f = rilebuf; f->base; f++)
+ if (f == rilebuf+RILES)
+ faterror("too many RILEs");
+# if maps_memory
+ f->deallocate = nothing_to_deallocate;
+# endif
+ if (!s) {
+ static unsigned char nothing;
+ f->base = &nothing; /* Any nonzero address will do. */
+ } else {
+ f->base = 0;
+# if has_map_fd
+ map_fd(
+ fd, (vm_offset_t)0, (vm_address_t*) &f->base,
+ TRUE, (vm_size_t)s
+ );
+ f->deallocate = map_fd_deallocate;
+# endif
+# if has_mmap
+ if (!f->base) {
+ catchmmapints();
+ f->base = (unsigned char *) mmap(
+ (char *)0, s, PROT_READ, MAP_SHARED,
+ fd, (off_t)0
+ );
+# ifndef MAP_FAILED
+# define MAP_FAILED (-1)
# endif
+ if (f->base == (unsigned char *) MAP_FAILED)
+ f->base = 0;
+ else {
+# if has_NFS && mmap_signal
+ /*
+ * On many hosts, the superuser
+ * can mmap an NFS file it can't read.
+ * So access the first page now, and print
+ * a nice message if a bus error occurs.
+ */
+ readAccessFilenameBuffer(name, f->base);
+# endif
+ }
+ f->deallocate = mmap_deallocate;
+ }
+# endif
+ if (!f->base) {
+ f->base = tnalloc(unsigned char, s);
+# if maps_memory
+ {
+ /*
+ * We can't map the file into memory for some reason.
+ * Read it into main memory all at once; this is
+ * the simplest substitute for memory mapping.
+ */
+ char *bufptr = (char *) f->base;
+ size_t bufsiz = s;
+ do {
+ ssize_t r = read(fd, bufptr, bufsiz);
+ switch (r) {
+ case -1:
+ efaterror(name);
+
+ case 0:
+ /* The file must have shrunk! */
+ status->st_size = s -= bufsiz;
+ bufsiz = 0;
+ break;
+
+ default:
+ bufptr += r;
+ bufsiz -= r;
+ break;
+ }
+ } while (bufsiz);
+ if (lseek(fd, (off_t)0, SEEK_SET) == -1)
+ efaterror(name);
+ f->deallocate = read_deallocate;
}
- f->ptr = f->base;
- f->lim = f->base + s;
-# if has_mmap
- f->fd = fd;
-# else
- f->readlim = f->base;
- f->stream = stream;
# endif
- if_advise_access(s, f, MADV_SEQUENTIAL);
- return f;
+ }
}
+ f->ptr = f->base;
+ f->lim = f->base + s;
+ f->fd = fd;
+# if !maps_memory
+ f->readlim = f->base;
+ f->stream = stream;
+# endif
+ if_advise_access(s, f, MADV_SEQUENTIAL);
+ return f;
+ }
# endif
}
}
-#if !has_mmap && large_memory
+#if !maps_memory && large_memory
int
Igetmore(f)
register RILE *f;
@@ -875,59 +1095,42 @@ advise_access(f, advice)
register RILE *f;
int advice;
{
- if (madvise((caddr_t)f->base, (size_t)(f->lim - f->base), advice) != 0)
- efaterror("madvise");
+ if (f->deallocate == mmap_deallocate)
+ VOID madvise((char *)f->base, (size_t)(f->lim - f->base), advice);
+ /* Don't worry if madvise fails; it's only advisory. */
}
#endif
RILE *
-#if has_mmap && large_memory
-I_open(filename, status)
+#if large_memory && maps_memory
+I_open(name, status)
#else
-Iopen(filename, mode, status)
- char const *mode;
+Iopen(name, type, status)
+ char const *type;
#endif
- char const *filename;
+ char const *name;
struct stat *status;
-/* Open FILENAME for reading, yield its descriptor, and set *STATUS. */
+/* Open NAME for reading, yield its descriptor, and set *STATUS. */
{
- int fd;
+ int fd = fdSafer(open(name, O_RDONLY
+# if OPEN_O_BINARY
+ | (strchr(type,'b') ? OPEN_O_BINARY : 0)
+# endif
+ ));
- if ((fd = open(filename,O_RDONLY|O_BINARY)) < 0)
+ if (fd < 0)
return 0;
-# if has_mmap && large_memory
- return fd2_RILE(fd, filename, status);
+# if large_memory && maps_memory
+ return fd2_RILE(fd, name, status);
# else
- return fd2RILE(fd, filename, mode, status);
+ return fd2RILE(fd, name, type, status);
# endif
}
-#if !large_memory
-# define Iclose(f) fclose(f)
-#else
- static int
- Iclose(f)
- register RILE *f;
- {
-# if has_mmap
- size_t s = f->lim - f->base;
- if (s && munmap((caddr_t)f->base, s) != 0)
- return -1;
- f->base = 0;
- return close(f->fd);
-# else
- tfree(f->base);
- f->base = 0;
- return fclose(f->stream);
-# endif
- }
-#endif
-
-
static int Oerrloop;
- exiting void
+ void
Oerror()
{
if (Oerrloop)
@@ -936,19 +1139,13 @@ Oerror()
efaterror("output error");
}
-exiting void Ieof() { fatserror("unexpected end of file"); }
-exiting void Ierror() { efaterror("input error"); }
+void Ieof() { fatserror("unexpected end of file"); }
+void Ierror() { efaterror("input error"); }
void testIerror(f) FILE *f; { if (ferror(f)) Ierror(); }
void testOerror(o) FILE *o; { if (ferror(o)) Oerror(); }
void Ifclose(f) RILE *f; { if (f && Iclose(f)!=0) Ierror(); }
-#ifndef FSYNC_ALL
void Ofclose(f) FILE *f; { if (f && fclose(f)!=0) Oerror(); }
-#else
-void Ofclose(f) FILE *f; { if (f && (fflush(f)!=0 ||
- fsync(fileno(f))!=0 ||
- fclose(f)!=0)) Oerror(); }
-#endif
void Izclose(p) RILE **p; { Ifclose(*p); *p = 0; }
void Ozclose(p) FILE **p; { Ofclose(*p); *p = 0; }
@@ -964,19 +1161,17 @@ testIeof(f)
void Irewind(f) FILE *f; { if (fseek(f,0L,SEEK_SET) != 0) Ierror(); }
#endif
-void eflush()
-{
- if (fflush(stderr) != 0 && !Oerrloop)
- Oerror();
-}
+void Orewind(f) FILE *f; { if (fseek(f,0L,SEEK_SET) != 0) Oerror(); }
+void aflush(f) FILE *f; { if (fflush(f) != 0) Oerror(); }
+void eflush() { if (fflush(stderr)!=0 && !Oerrloop) Oerror(); }
void oflush()
{
if (fflush(workstdout ? workstdout : stdout) != 0 && !Oerrloop)
Oerror();
}
- static exiting void
+ void
fatcleanup(already_newline)
int already_newline;
{
@@ -984,8 +1179,38 @@ fatcleanup(already_newline)
exiterr();
}
-static void errsay() { oflush(); aprintf(stderr,"%s error: ",cmdid); nerror++; }
-static void fatsay() { oflush(); VOID fprintf(stderr,"%s error: ",cmdid); }
+ static void
+startsay(s, t)
+ const char *s, *t;
+{
+ oflush();
+ if (s)
+ aprintf(stderr, "%s: %s: %s", cmdid, s, t);
+ else
+ aprintf(stderr, "%s: %s", cmdid, t);
+}
+
+ static void
+fatsay(s)
+ char const *s;
+{
+ startsay(s, "");
+}
+
+ static void
+errsay(s)
+ char const *s;
+{
+ fatsay(s);
+ nerror++;
+}
+
+ static void
+warnsay(s)
+ char const *s;
+{
+ startsay(s, "warning: ");
+}
void eerror(s) char const *s; { enerror(errno,s); }
@@ -994,20 +1219,20 @@ enerror(e,s)
int e;
char const *s;
{
- errsay();
+ errsay((char const*)0);
errno = e;
perror(s);
eflush();
}
-exiting void efaterror(s) char const *s; { enfaterror(errno,s); }
+void efaterror(s) char const *s; { enfaterror(errno,s); }
- exiting void
+ void
enfaterror(e,s)
int e;
char const *s;
{
- fatsay();
+ fatsay((char const*)0);
errno = e;
perror(s);
fatcleanup(true);
@@ -1022,7 +1247,41 @@ error(char const *format,...)
/* non-fatal error */
{
va_list args;
- errsay();
+ errsay((char const*)0);
+ vararg_start(args, format);
+ fvfprintf(stderr, format, args);
+ va_end(args);
+ afputc('\n',stderr);
+ eflush();
+}
+
+#if has_prototypes
+ void
+rcserror(char const *format,...)
+#else
+ /*VARARGS1*/ void rcserror(format, va_alist) char const *format; va_dcl
+#endif
+/* non-fatal RCS file error */
+{
+ va_list args;
+ errsay(RCSname);
+ vararg_start(args, format);
+ fvfprintf(stderr, format, args);
+ va_end(args);
+ afputc('\n',stderr);
+ eflush();
+}
+
+#if has_prototypes
+ void
+workerror(char const *format,...)
+#else
+ /*VARARGS1*/ void workerror(format, va_alist) char const *format; va_dcl
+#endif
+/* non-fatal working file error */
+{
+ va_list args;
+ errsay(workname);
vararg_start(args, format);
fvfprintf(stderr, format, args);
va_end(args);
@@ -1031,17 +1290,17 @@ error(char const *format,...)
}
#if has_prototypes
- exiting void
+ void
fatserror(char const *format,...)
#else
- /*VARARGS1*/ exiting void
+ /*VARARGS1*/ void
fatserror(format, va_alist) char const *format; va_dcl
#endif
-/* fatal syntax error */
+/* fatal RCS file syntax error */
{
va_list args;
oflush();
- VOID fprintf(stderr, "%s: %s:%lu: ", cmdid, RCSfilename, rcsline);
+ VOID fprintf(stderr, "%s: %s:%ld: ", cmdid, RCSname, rcsline);
vararg_start(args, format);
fvfprintf(stderr, format, args);
va_end(args);
@@ -1049,16 +1308,16 @@ fatserror(char const *format,...)
}
#if has_prototypes
- exiting void
+ void
faterror(char const *format,...)
#else
- /*VARARGS1*/ exiting void faterror(format, va_alist)
+ /*VARARGS1*/ void faterror(format, va_alist)
char const *format; va_dcl
#endif
/* fatal error, terminates program after cleanup */
{
va_list args;
- fatsay();
+ fatsay((char const*)0);
vararg_start(args, format);
fvfprintf(stderr, format, args);
va_end(args);
@@ -1067,20 +1326,76 @@ faterror(char const *format,...)
#if has_prototypes
void
-warn(char const *format,...)
+rcsfaterror(char const *format,...)
#else
- /*VARARGS1*/ void warn(format, va_alist) char const *format; va_dcl
+ /*VARARGS1*/ void rcsfaterror(format, va_alist)
+ char const *format; va_dcl
#endif
-/* prints a warning message */
+/* fatal RCS file error, terminates program after cleanup */
{
va_list args;
- oflush();
- aprintf(stderr,"%s warning: ",cmdid);
+ fatsay(RCSname);
vararg_start(args, format);
fvfprintf(stderr, format, args);
va_end(args);
- afputc('\n',stderr);
- eflush();
+ fatcleanup(false);
+}
+
+#if has_prototypes
+ void
+warn(char const *format,...)
+#else
+ /*VARARGS1*/ void warn(format, va_alist) char const *format; va_dcl
+#endif
+/* warning */
+{
+ va_list args;
+ if (!quietflag) {
+ warnsay((char *)0);
+ vararg_start(args, format);
+ fvfprintf(stderr, format, args);
+ va_end(args);
+ afputc('\n', stderr);
+ eflush();
+ }
+}
+
+#if has_prototypes
+ void
+rcswarn(char const *format,...)
+#else
+ /*VARARGS1*/ void rcswarn(format, va_alist) char const *format; va_dcl
+#endif
+/* RCS file warning */
+{
+ va_list args;
+ if (!quietflag) {
+ warnsay(RCSname);
+ vararg_start(args, format);
+ fvfprintf(stderr, format, args);
+ va_end(args);
+ afputc('\n', stderr);
+ eflush();
+ }
+}
+
+#if has_prototypes
+ void
+workwarn(char const *format,...)
+#else
+ /*VARARGS1*/ void workwarn(format, va_alist) char const *format; va_dcl
+#endif
+/* working file warning */
+{
+ va_list args;
+ if (!quietflag) {
+ warnsay(workname);
+ vararg_start(args, format);
+ fvfprintf(stderr, format, args);
+ va_end(args);
+ afputc('\n', stderr);
+ eflush();
+ }
}
void
@@ -1115,12 +1430,11 @@ diagnose(char const *format,...)
void
afputc(c, f)
-/* Function: afputc(c,f) acts like aputc(c,f), but is smaller and slower.
- */
+/* afputc(c,f); acts like aputc_(c,f) but is smaller and slower. */
int c;
register FILE *f;
{
- aputc(c,f);
+ aputc_(c,f)
}
@@ -1151,6 +1465,7 @@ fvfprintf(FILE *stream, char const *format, va_list args)
{
#if has_vfprintf
if (vfprintf(stream, format, args) < 0)
+ Oerror();
#else
# if has__doprintf
_doprintf(stream, format, args);
@@ -1166,8 +1481,8 @@ fvfprintf(FILE *stream, char const *format, va_list args)
# endif
# endif
if (ferror(stream))
-#endif
Oerror();
+#endif
}
#if has_prototypes
@@ -1248,7 +1563,7 @@ int argc; char * argv[];
exitmain(EXIT_SUCCESS);
}
-exiting void exiterr() { _exit(EXIT_FAILURE); }
+void exiterr() { _exit(EXIT_FAILURE); }
#endif
OpenPOWER on IntegriCloud