Deleted Added
full compact
rcsbase.h (22996) rcsbase.h (25699)
1/* RCS common definitions and data structures */
2
1/* RCS common definitions and data structures */
2
3#define RCSBASE "$Id$"
3#define RCSBASE "$Id: rcsbase.h,v 1.8 1997/02/22 15:47:33 peter Exp $"
4
5/* Copyright 1982, 1988, 1989 Walter Tichy
6 Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
7 Distributed under license by the Free Software Foundation, Inc.
8
9This file is part of RCS.
10
11RCS is free software; you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published by
13the Free Software Foundation; either version 2, or (at your option)
14any later version.
15
16RCS is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
22along with RCS; see the file COPYING.
23If not, write to the Free Software Foundation,
2459 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26Report problems and direct all questions to:
27
28 rcs-bugs@cs.purdue.edu
29
30*/
31
32/*
33 * Revision 5.20 1995/06/16 06:19:24 eggert
34 * Update FSF address.
35 *
36 * Revision 5.19 1995/06/01 16:23:43 eggert
37 * (SIZEABLE_PATH): Don't depend on PATH_MAX: it's not worth configuring.
38 * (Ioffset_type,BINARY_EXPAND,MIN_UNEXPAND,MIN_UNCHANGED_EXPAND): New macros.
39 * (maps_memory): New macro; replaces many instances of `has_mmap'.
40 * (cacheptr): Renamed from cachetell.
41 * (struct RILE): New alternate name for RILE; the type is now recursive.
42 * (deallocate): New member for RILE, used for generic buffer deallocation.
43 * (cacheunget_): No longer take a failure arg; just call Ierror on failure.
44 * (struct rcslock): Renamed from struct lock, to avoid collisions with
45 * system headers on some hosts. All users changed.
46 * (basefilename): Renamed from basename, likewise.
47 * (dirtpname): Remove; no longer external.
48 * (dirlen, dateform): Remove; no longer used.
49 * (cmpdate, fopenSafer, fdSafer, readAccessFilenameBuffer): New functions.
50 * (zonelenmax): Increase to 9 for full ISO 8601 format.
51 * (catchmmapints): Depend on has_NFS.
52 *
53 * Revision 5.18 1994/03/17 14:05:48 eggert
54 * Add primitives for reading backwards from a RILE;
55 * this is needed to go back and find the $Log prefix.
56 * Specify subprocess input via file descriptor, not file name. Remove lint.
57 *
58 * Revision 5.17 1993/11/09 17:40:15 eggert
59 * Move RCS-specific time handling into rcstime.c.
60 * printf_string now takes two arguments, alas.
61 *
62 * Revision 5.16 1993/11/03 17:42:27 eggert
63 * Don't arbitrarily limit the number of joins. Remove `nil'.
64 * Add Name keyword. Don't discard ignored phrases.
65 * Add support for merge -A vs -E, and allow up to three labels.
66 * Improve quality of diagnostics and prototypes.
67 *
68 * Revision 5.15 1992/07/28 16:12:44 eggert
69 * Statement macro names now end in _.
70 *
71 * Revision 5.14 1992/02/17 23:02:22 eggert
72 * Add -T support. Work around NFS mmap SIGBUS problem.
73 *
74 * Revision 5.13 1992/01/24 18:44:19 eggert
75 * Add support for bad_creat0. lint -> RCS_lint
76 *
77 * Revision 5.12 1992/01/06 02:42:34 eggert
78 * while (E) ; -> while (E) continue;
79 *
80 * Revision 5.11 1991/10/07 17:32:46 eggert
81 * Support piece tables even if !has_mmap.
82 *
83 * Revision 5.10 1991/09/24 00:28:39 eggert
84 * Remove unexported functions.
85 *
86 * Revision 5.9 1991/08/19 03:13:55 eggert
87 * Add piece tables and other tuneups, and NFS workarounds.
88 *
89 * Revision 5.8 1991/04/21 11:58:20 eggert
90 * Add -x, RCSINIT, MS-DOS support.
91 *
92 * Revision 5.7 1991/02/28 19:18:50 eggert
93 * Try setuid() if seteuid() doesn't work.
94 *
95 * Revision 5.6 1991/02/26 17:48:37 eggert
96 * Support new link behavior. Move ANSI C / Posix declarations into conf.sh.
97 *
98 * Revision 5.5 1990/12/04 05:18:43 eggert
99 * Use -I for prompts and -q for diagnostics.
100 *
101 * Revision 5.4 1990/11/01 05:03:35 eggert
102 * Don't assume that builtins are functions; they may be macros.
103 * Permit arbitrary data in logs.
104 *
105 * Revision 5.3 1990/09/26 23:36:58 eggert
106 * Port wait() to non-Posix ANSI C hosts.
107 *
108 * Revision 5.2 1990/09/04 08:02:20 eggert
109 * Don't redefine NAME_MAX, PATH_MAX.
110 * Improve incomplete line handling. Standardize yes-or-no procedure.
111 *
112 * Revision 5.1 1990/08/29 07:13:53 eggert
113 * Add -kkvl. Fix type typos exposed by porting. Clean old log messages too.
114 *
115 * Revision 5.0 1990/08/22 08:12:44 eggert
116 * Adjust ANSI C / Posix support. Add -k, -V, setuid. Don't call access().
117 * Remove compile-time limits; use malloc instead.
118 * Ansify and Posixate. Add support for ISO 8859.
119 * Remove snoop and v2 support.
120 *
121 * Revision 4.9 89/05/01 15:17:14 narten
122 * botched previous USG fix
123 *
124 * Revision 4.8 89/05/01 14:53:05 narten
125 * changed #include <strings.h> -> string.h for USG systems.
126 *
127 * Revision 4.7 88/11/08 15:58:45 narten
128 * removed defs for functions loaded from libraries
129 *
130 * Revision 4.6 88/08/09 19:12:36 eggert
131 * Shrink stdio code size; remove lint; permit -Dhshsize=nn.
132 *
133 * Revision 4.5 87/12/18 17:06:41 narten
134 * made removed BSD ifdef, now uses V4_2BSD
135 *
136 * Revision 4.4 87/10/18 10:29:49 narten
137 * Updating version numbers
138 * Changes relative to 1.1 are actually relative to 4.2
139 *
140 * Revision 1.3 87/09/24 14:02:25 narten
141 * changes for lint
142 *
143 * Revision 1.2 87/03/27 14:22:02 jenkins
144 * Port to suns
145 *
146 * Revision 4.2 83/12/20 16:04:20 wft
147 * merged 3.6.1.1 and 4.1 (SMALLOG, logsize).
148 * moved setting of STRICT_LOCKING to Makefile.
149 * changed DOLLAR to UNKN (conflict with KDELIM).
150 *
151 * Revision 4.1 83/05/04 09:12:41 wft
152 * Added markers Id and RCSfile.
153 * Added Dbranch for default branches.
154 *
155 * Revision 3.6.1.1 83/12/02 21:56:22 wft
156 * Increased logsize, added macro SMALLOG.
157 *
158 * Revision 3.6 83/01/15 16:43:28 wft
159 * 4.2 prerelease
160 *
161 * Revision 3.6 83/01/15 16:43:28 wft
162 * Replaced dbm.h with BYTESIZ, fixed definition of rindex().
163 * Added variants of NCPFN and NCPPN for bsd 4.2, selected by defining V4_2BSD.
164 * Added macro DELNUMFORM to have uniform format for printing delta text nodes.
165 * Added macro DELETE to mark deleted deltas.
166 *
167 * Revision 3.5 82/12/10 12:16:56 wft
168 * Added two forms of DATEFORM, one using %02d, the other %.2d.
169 *
170 * Revision 3.4 82/12/04 20:01:25 wft
171 * added LOCKER, Locker, and USG (redefinition of rindex).
172 *
173 * Revision 3.3 82/12/03 12:22:04 wft
174 * Added dbm.h, stdio.h, RCSBASE, RCSSEP, RCSSUF, WORKMODE, TMPFILE3,
175 * PRINTDATE, PRINTTIME, map, and ctab; removed Suffix. Redefined keyvallength
176 * using NCPPN. Changed putc() to abort on write error.
177 *
178 * Revision 3.2 82/10/18 15:03:52 wft
179 * added macro STRICT_LOCKING, removed RCSUMASK.
180 * renamed JOINFILE[1,2] to JOINFIL[1,2].
181 *
182 * Revision 3.1 82/10/11 19:41:17 wft
183 * removed NBPW, NBPC, NCPW.
184 * added typdef int void to aid compiling
185 */
186
187
188#include "conf.h"
189
190
191#define EXIT_TROUBLE DIFF_TROUBLE
192
193#ifdef _POSIX_PATH_MAX
194# define SIZEABLE_PATH _POSIX_PATH_MAX
195#else
196# define SIZEABLE_PATH 255 /* size of a large path; not a hard limit */
197#endif
198
199/* for traditional C hosts with unusual size arguments */
200#define Fread(p,s,n,f) fread(p, (freadarg_type)(s), (freadarg_type)(n), f)
201#define Fwrite(p,s,n,f) fwrite(p, (freadarg_type)(s), (freadarg_type)(n), f)
202
203
204/*
205 * Parameters
206 */
207
208/* backwards compatibility with old versions of RCS */
209#define VERSION_min 3 /* old output RCS format supported */
210#define VERSION_max 5 /* newest output RCS format supported */
211#ifndef VERSION_DEFAULT /* default RCS output format */
212# define VERSION_DEFAULT VERSION_max
213#endif
214#define VERSION(n) ((n) - VERSION_DEFAULT) /* internally, 0 is the default */
215
216#ifndef STRICT_LOCKING
217#define STRICT_LOCKING 1
218#endif
219 /* 0 sets the default locking to non-strict; */
220 /* used in experimental environments. */
221 /* 1 sets the default locking to strict; */
222 /* used in production environments. */
223
224#define yearlength 16 /* (good through AD 9,999,999,999,999,999) */
225#define datesize (yearlength+16) /* size of output of time2date */
226#define RCSTMPPREFIX '_' /* prefix for temp files in working dir */
227#define KDELIM '$' /* delimiter for keywords */
228#define VDELIM ':' /* separates keywords from values */
229#define DEFAULTSTATE "Exp" /* default state of revisions */
230
231
232
233#define true 1
234#define false 0
235
236
237/*
238 * RILE - readonly file
239 * declarecache; - declares local cache for RILE variable(s)
240 * setupcache - sets up the local RILE cache, but does not initialize it
241 * cache, uncache - caches and uncaches the local RILE;
242 * (uncache,cache) is needed around functions that advance the RILE pointer
243 * Igeteof_(f,c,s) - get a char c from f, executing statement s at EOF
244 * cachegeteof_(c,s) - Igeteof_ applied to the local RILE
245 * Iget_(f,c) - like Igeteof_, except EOF is an error
246 * cacheget_(c) - Iget_ applied to the local RILE
247 * cacheunget_(f,c,s) - read c backwards from cached f, executing s at BOF
248 * Ifileno, Ioffset_type, Irewind, Itell - analogs to stdio routines
249 *
250 * By conventions, macros whose names end in _ are statements, not expressions.
251 * Following such macros with `; else' results in a syntax error.
252 */
253
254#define maps_memory (has_map_fd || has_mmap)
255
256#if large_memory
257 typedef unsigned char const *Iptr_type;
258 typedef struct RILE {
259 Iptr_type ptr, lim;
260 unsigned char *base; /* not Iptr_type for lint's sake */
261 unsigned char *readlim;
262 int fd;
263# if maps_memory
264 void (*deallocate) P((struct RILE *));
265# else
266 FILE *stream;
267# endif
268 } RILE;
269# if maps_memory
270# define declarecache register Iptr_type ptr, lim
271# define setupcache(f) (lim = (f)->lim)
272# define Igeteof_(f,c,s) if ((f)->ptr==(f)->lim) s else (c)= *(f)->ptr++;
273# define cachegeteof_(c,s) if (ptr==lim) s else (c)= *ptr++;
274# else
275 int Igetmore P((RILE*));
276# define declarecache register Iptr_type ptr; register RILE *rRILE
277# define setupcache(f) (rRILE = (f))
278# define Igeteof_(f,c,s) if ((f)->ptr==(f)->readlim && !Igetmore(f)) s else (c)= *(f)->ptr++;
279# define cachegeteof_(c,s) if (ptr==rRILE->readlim && !Igetmore(rRILE)) s else (c)= *ptr++;
280# endif
281# define uncache(f) ((f)->ptr = ptr)
282# define cache(f) (ptr = (f)->ptr)
283# define Iget_(f,c) Igeteof_(f,c,Ieof();)
284# define cacheget_(c) cachegeteof_(c,Ieof();)
285# define cacheunget_(f,c) (c)=(--ptr)[-1];
286# define Ioffset_type size_t
287# define Itell(f) ((f)->ptr - (f)->base)
288# define Irewind(f) ((f)->ptr = (f)->base)
289# define cacheptr() ptr
290# define Ifileno(f) ((f)->fd)
291#else
292# define RILE FILE
293# define declarecache register FILE *ptr
294# define setupcache(f) (ptr = (f))
295# define uncache(f)
296# define cache(f)
297# define Igeteof_(f,c,s) {if(((c)=getc(f))==EOF){testIerror(f);if(feof(f))s}}
298# define cachegeteof_(c,s) Igeteof_(ptr,c,s)
299# define Iget_(f,c) { if (((c)=getc(f))==EOF) testIeof(f); }
300# define cacheget_(c) Iget_(ptr,c)
301# define cacheunget_(f,c) if(fseek(ptr,-2L,SEEK_CUR))Ierror();else cacheget_(c)
302# define Ioffset_type long
303# define Itell(f) ftell(f)
304# define Ifileno(f) fileno(f)
305#endif
306
307/* Print a char, but abort on write error. */
308#define aputc_(c,o) { if (putc(c,o)==EOF) testOerror(o); }
309
310/* Get a character from an RCS file, perhaps copying to a new RCS file. */
311#define GETCeof_(o,c,s) { cachegeteof_(c,s) if (o) aputc_(c,o) }
312#define GETC_(o,c) { cacheget_(c) if (o) aputc_(c,o) }
313
314
315#define WORKMODE(RCSmode, writable) (((RCSmode)&(mode_t)~(S_IWUSR|S_IWGRP|S_IWOTH)) | ((writable)?S_IWUSR:0))
316/* computes mode of working file: same as RCSmode, but write permission */
317/* determined by writable */
318
319
320/* character classes and token codes */
321enum tokens {
322/* classes */ DELIM, DIGIT, IDCHAR, NEWLN, LETTER, Letter,
323 PERIOD, SBEGIN, SPACE, UNKN,
324/* tokens */ COLON, ID, NUM, SEMI, STRING
325};
326
327#define SDELIM '@' /* the actual character is needed for string handling*/
328/* SDELIM must be consistent with ctab[], so that ctab[SDELIM]==SBEGIN.
329 * there should be no overlap among SDELIM, KDELIM, and VDELIM
330 */
331
332#define isdigit(c) (((unsigned)(c)-'0') <= 9) /* faster than ctab[c]==DIGIT */
333
334
335
336
337
338/***************************************
339 * Data structures for the symbol table
340 ***************************************/
341
342/* Buffer of arbitrary data */
343struct buf {
344 char *string;
345 size_t size;
346};
347struct cbuf {
348 char const *string;
349 size_t size;
350};
351
352/* Hash table entry */
353struct hshentry {
354 char const * num; /* pointer to revision number (ASCIZ) */
355 char const * date; /* pointer to date of checkin */
356 char const * author; /* login of person checking in */
357 char const * lockedby; /* who locks the revision */
358 char const * state; /* state of revision (Exp by default) */
359 char const * name; /* name (if any) by which retrieved */
360 struct cbuf log; /* log message requested at checkin */
361 struct branchhead * branches; /* list of first revisions on branches*/
362 struct cbuf ig; /* ignored phrases in admin part */
363 struct cbuf igtext; /* ignored phrases in deltatext part */
364 struct hshentry * next; /* next revision on same branch */
365 struct hshentry * nexthsh; /* next revision with same hash value */
366 long insertlns;/* lines inserted (computed by rlog) */
367 long deletelns;/* lines deleted (computed by rlog) */
368 char selector; /* true if selected, false if deleted */
369};
370
371/* list of hash entries */
372struct hshentries {
373 struct hshentries *rest;
374 struct hshentry *first;
375};
376
377/* list element for branch lists */
378struct branchhead {
379 struct hshentry * hsh;
380 struct branchhead * nextbranch;
381};
382
383/* accesslist element */
384struct access {
385 char const * login;
386 struct access * nextaccess;
387};
388
389/* list element for locks */
390struct rcslock {
391 char const * login;
392 struct hshentry * delta;
393 struct rcslock * nextlock;
394};
395
396/* list element for symbolic names */
397struct assoc {
398 char const * symbol;
399 char const * num;
400 struct assoc * nextassoc;
401};
402
403
404#define mainArgs (argc,argv) int argc; char **argv;
405
406#if RCS_lint
407# define libId(name,rcsid)
408# define mainProg(name,cmd,rcsid) int name mainArgs
409#else
410# define libId(name,rcsid) char const name[] = rcsid;
411# define mainProg(n,c,i) char const Copyright[] = "Copyright 1982,1988,1989 Walter F. Tichy, Purdue CS\nCopyright 1990,1991,1992,1993,1994,1995 Paul Eggert", baseid[] = RCSBASE, cmdid[] = c; libId(n,i) int main P((int,char**)); int main mainArgs
412#endif
413
414/*
415 * Markers for keyword expansion (used in co and ident)
416 * Every byte must have class LETTER or Letter.
417 */
418#define AUTHOR "Author"
419#define DATE "Date"
420#define HEADER "Header"
421#define IDH "Id"
422#define LOCKER "Locker"
423#define LOG "Log"
424#define NAME "Name"
425#define RCSFILE "RCSfile"
426#define REVISION "Revision"
427#define SOURCE "Source"
428#define STATE "State"
4
5/* Copyright 1982, 1988, 1989 Walter Tichy
6 Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
7 Distributed under license by the Free Software Foundation, Inc.
8
9This file is part of RCS.
10
11RCS is free software; you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published by
13the Free Software Foundation; either version 2, or (at your option)
14any later version.
15
16RCS is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
22along with RCS; see the file COPYING.
23If not, write to the Free Software Foundation,
2459 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26Report problems and direct all questions to:
27
28 rcs-bugs@cs.purdue.edu
29
30*/
31
32/*
33 * Revision 5.20 1995/06/16 06:19:24 eggert
34 * Update FSF address.
35 *
36 * Revision 5.19 1995/06/01 16:23:43 eggert
37 * (SIZEABLE_PATH): Don't depend on PATH_MAX: it's not worth configuring.
38 * (Ioffset_type,BINARY_EXPAND,MIN_UNEXPAND,MIN_UNCHANGED_EXPAND): New macros.
39 * (maps_memory): New macro; replaces many instances of `has_mmap'.
40 * (cacheptr): Renamed from cachetell.
41 * (struct RILE): New alternate name for RILE; the type is now recursive.
42 * (deallocate): New member for RILE, used for generic buffer deallocation.
43 * (cacheunget_): No longer take a failure arg; just call Ierror on failure.
44 * (struct rcslock): Renamed from struct lock, to avoid collisions with
45 * system headers on some hosts. All users changed.
46 * (basefilename): Renamed from basename, likewise.
47 * (dirtpname): Remove; no longer external.
48 * (dirlen, dateform): Remove; no longer used.
49 * (cmpdate, fopenSafer, fdSafer, readAccessFilenameBuffer): New functions.
50 * (zonelenmax): Increase to 9 for full ISO 8601 format.
51 * (catchmmapints): Depend on has_NFS.
52 *
53 * Revision 5.18 1994/03/17 14:05:48 eggert
54 * Add primitives for reading backwards from a RILE;
55 * this is needed to go back and find the $Log prefix.
56 * Specify subprocess input via file descriptor, not file name. Remove lint.
57 *
58 * Revision 5.17 1993/11/09 17:40:15 eggert
59 * Move RCS-specific time handling into rcstime.c.
60 * printf_string now takes two arguments, alas.
61 *
62 * Revision 5.16 1993/11/03 17:42:27 eggert
63 * Don't arbitrarily limit the number of joins. Remove `nil'.
64 * Add Name keyword. Don't discard ignored phrases.
65 * Add support for merge -A vs -E, and allow up to three labels.
66 * Improve quality of diagnostics and prototypes.
67 *
68 * Revision 5.15 1992/07/28 16:12:44 eggert
69 * Statement macro names now end in _.
70 *
71 * Revision 5.14 1992/02/17 23:02:22 eggert
72 * Add -T support. Work around NFS mmap SIGBUS problem.
73 *
74 * Revision 5.13 1992/01/24 18:44:19 eggert
75 * Add support for bad_creat0. lint -> RCS_lint
76 *
77 * Revision 5.12 1992/01/06 02:42:34 eggert
78 * while (E) ; -> while (E) continue;
79 *
80 * Revision 5.11 1991/10/07 17:32:46 eggert
81 * Support piece tables even if !has_mmap.
82 *
83 * Revision 5.10 1991/09/24 00:28:39 eggert
84 * Remove unexported functions.
85 *
86 * Revision 5.9 1991/08/19 03:13:55 eggert
87 * Add piece tables and other tuneups, and NFS workarounds.
88 *
89 * Revision 5.8 1991/04/21 11:58:20 eggert
90 * Add -x, RCSINIT, MS-DOS support.
91 *
92 * Revision 5.7 1991/02/28 19:18:50 eggert
93 * Try setuid() if seteuid() doesn't work.
94 *
95 * Revision 5.6 1991/02/26 17:48:37 eggert
96 * Support new link behavior. Move ANSI C / Posix declarations into conf.sh.
97 *
98 * Revision 5.5 1990/12/04 05:18:43 eggert
99 * Use -I for prompts and -q for diagnostics.
100 *
101 * Revision 5.4 1990/11/01 05:03:35 eggert
102 * Don't assume that builtins are functions; they may be macros.
103 * Permit arbitrary data in logs.
104 *
105 * Revision 5.3 1990/09/26 23:36:58 eggert
106 * Port wait() to non-Posix ANSI C hosts.
107 *
108 * Revision 5.2 1990/09/04 08:02:20 eggert
109 * Don't redefine NAME_MAX, PATH_MAX.
110 * Improve incomplete line handling. Standardize yes-or-no procedure.
111 *
112 * Revision 5.1 1990/08/29 07:13:53 eggert
113 * Add -kkvl. Fix type typos exposed by porting. Clean old log messages too.
114 *
115 * Revision 5.0 1990/08/22 08:12:44 eggert
116 * Adjust ANSI C / Posix support. Add -k, -V, setuid. Don't call access().
117 * Remove compile-time limits; use malloc instead.
118 * Ansify and Posixate. Add support for ISO 8859.
119 * Remove snoop and v2 support.
120 *
121 * Revision 4.9 89/05/01 15:17:14 narten
122 * botched previous USG fix
123 *
124 * Revision 4.8 89/05/01 14:53:05 narten
125 * changed #include <strings.h> -> string.h for USG systems.
126 *
127 * Revision 4.7 88/11/08 15:58:45 narten
128 * removed defs for functions loaded from libraries
129 *
130 * Revision 4.6 88/08/09 19:12:36 eggert
131 * Shrink stdio code size; remove lint; permit -Dhshsize=nn.
132 *
133 * Revision 4.5 87/12/18 17:06:41 narten
134 * made removed BSD ifdef, now uses V4_2BSD
135 *
136 * Revision 4.4 87/10/18 10:29:49 narten
137 * Updating version numbers
138 * Changes relative to 1.1 are actually relative to 4.2
139 *
140 * Revision 1.3 87/09/24 14:02:25 narten
141 * changes for lint
142 *
143 * Revision 1.2 87/03/27 14:22:02 jenkins
144 * Port to suns
145 *
146 * Revision 4.2 83/12/20 16:04:20 wft
147 * merged 3.6.1.1 and 4.1 (SMALLOG, logsize).
148 * moved setting of STRICT_LOCKING to Makefile.
149 * changed DOLLAR to UNKN (conflict with KDELIM).
150 *
151 * Revision 4.1 83/05/04 09:12:41 wft
152 * Added markers Id and RCSfile.
153 * Added Dbranch for default branches.
154 *
155 * Revision 3.6.1.1 83/12/02 21:56:22 wft
156 * Increased logsize, added macro SMALLOG.
157 *
158 * Revision 3.6 83/01/15 16:43:28 wft
159 * 4.2 prerelease
160 *
161 * Revision 3.6 83/01/15 16:43:28 wft
162 * Replaced dbm.h with BYTESIZ, fixed definition of rindex().
163 * Added variants of NCPFN and NCPPN for bsd 4.2, selected by defining V4_2BSD.
164 * Added macro DELNUMFORM to have uniform format for printing delta text nodes.
165 * Added macro DELETE to mark deleted deltas.
166 *
167 * Revision 3.5 82/12/10 12:16:56 wft
168 * Added two forms of DATEFORM, one using %02d, the other %.2d.
169 *
170 * Revision 3.4 82/12/04 20:01:25 wft
171 * added LOCKER, Locker, and USG (redefinition of rindex).
172 *
173 * Revision 3.3 82/12/03 12:22:04 wft
174 * Added dbm.h, stdio.h, RCSBASE, RCSSEP, RCSSUF, WORKMODE, TMPFILE3,
175 * PRINTDATE, PRINTTIME, map, and ctab; removed Suffix. Redefined keyvallength
176 * using NCPPN. Changed putc() to abort on write error.
177 *
178 * Revision 3.2 82/10/18 15:03:52 wft
179 * added macro STRICT_LOCKING, removed RCSUMASK.
180 * renamed JOINFILE[1,2] to JOINFIL[1,2].
181 *
182 * Revision 3.1 82/10/11 19:41:17 wft
183 * removed NBPW, NBPC, NCPW.
184 * added typdef int void to aid compiling
185 */
186
187
188#include "conf.h"
189
190
191#define EXIT_TROUBLE DIFF_TROUBLE
192
193#ifdef _POSIX_PATH_MAX
194# define SIZEABLE_PATH _POSIX_PATH_MAX
195#else
196# define SIZEABLE_PATH 255 /* size of a large path; not a hard limit */
197#endif
198
199/* for traditional C hosts with unusual size arguments */
200#define Fread(p,s,n,f) fread(p, (freadarg_type)(s), (freadarg_type)(n), f)
201#define Fwrite(p,s,n,f) fwrite(p, (freadarg_type)(s), (freadarg_type)(n), f)
202
203
204/*
205 * Parameters
206 */
207
208/* backwards compatibility with old versions of RCS */
209#define VERSION_min 3 /* old output RCS format supported */
210#define VERSION_max 5 /* newest output RCS format supported */
211#ifndef VERSION_DEFAULT /* default RCS output format */
212# define VERSION_DEFAULT VERSION_max
213#endif
214#define VERSION(n) ((n) - VERSION_DEFAULT) /* internally, 0 is the default */
215
216#ifndef STRICT_LOCKING
217#define STRICT_LOCKING 1
218#endif
219 /* 0 sets the default locking to non-strict; */
220 /* used in experimental environments. */
221 /* 1 sets the default locking to strict; */
222 /* used in production environments. */
223
224#define yearlength 16 /* (good through AD 9,999,999,999,999,999) */
225#define datesize (yearlength+16) /* size of output of time2date */
226#define RCSTMPPREFIX '_' /* prefix for temp files in working dir */
227#define KDELIM '$' /* delimiter for keywords */
228#define VDELIM ':' /* separates keywords from values */
229#define DEFAULTSTATE "Exp" /* default state of revisions */
230
231
232
233#define true 1
234#define false 0
235
236
237/*
238 * RILE - readonly file
239 * declarecache; - declares local cache for RILE variable(s)
240 * setupcache - sets up the local RILE cache, but does not initialize it
241 * cache, uncache - caches and uncaches the local RILE;
242 * (uncache,cache) is needed around functions that advance the RILE pointer
243 * Igeteof_(f,c,s) - get a char c from f, executing statement s at EOF
244 * cachegeteof_(c,s) - Igeteof_ applied to the local RILE
245 * Iget_(f,c) - like Igeteof_, except EOF is an error
246 * cacheget_(c) - Iget_ applied to the local RILE
247 * cacheunget_(f,c,s) - read c backwards from cached f, executing s at BOF
248 * Ifileno, Ioffset_type, Irewind, Itell - analogs to stdio routines
249 *
250 * By conventions, macros whose names end in _ are statements, not expressions.
251 * Following such macros with `; else' results in a syntax error.
252 */
253
254#define maps_memory (has_map_fd || has_mmap)
255
256#if large_memory
257 typedef unsigned char const *Iptr_type;
258 typedef struct RILE {
259 Iptr_type ptr, lim;
260 unsigned char *base; /* not Iptr_type for lint's sake */
261 unsigned char *readlim;
262 int fd;
263# if maps_memory
264 void (*deallocate) P((struct RILE *));
265# else
266 FILE *stream;
267# endif
268 } RILE;
269# if maps_memory
270# define declarecache register Iptr_type ptr, lim
271# define setupcache(f) (lim = (f)->lim)
272# define Igeteof_(f,c,s) if ((f)->ptr==(f)->lim) s else (c)= *(f)->ptr++;
273# define cachegeteof_(c,s) if (ptr==lim) s else (c)= *ptr++;
274# else
275 int Igetmore P((RILE*));
276# define declarecache register Iptr_type ptr; register RILE *rRILE
277# define setupcache(f) (rRILE = (f))
278# define Igeteof_(f,c,s) if ((f)->ptr==(f)->readlim && !Igetmore(f)) s else (c)= *(f)->ptr++;
279# define cachegeteof_(c,s) if (ptr==rRILE->readlim && !Igetmore(rRILE)) s else (c)= *ptr++;
280# endif
281# define uncache(f) ((f)->ptr = ptr)
282# define cache(f) (ptr = (f)->ptr)
283# define Iget_(f,c) Igeteof_(f,c,Ieof();)
284# define cacheget_(c) cachegeteof_(c,Ieof();)
285# define cacheunget_(f,c) (c)=(--ptr)[-1];
286# define Ioffset_type size_t
287# define Itell(f) ((f)->ptr - (f)->base)
288# define Irewind(f) ((f)->ptr = (f)->base)
289# define cacheptr() ptr
290# define Ifileno(f) ((f)->fd)
291#else
292# define RILE FILE
293# define declarecache register FILE *ptr
294# define setupcache(f) (ptr = (f))
295# define uncache(f)
296# define cache(f)
297# define Igeteof_(f,c,s) {if(((c)=getc(f))==EOF){testIerror(f);if(feof(f))s}}
298# define cachegeteof_(c,s) Igeteof_(ptr,c,s)
299# define Iget_(f,c) { if (((c)=getc(f))==EOF) testIeof(f); }
300# define cacheget_(c) Iget_(ptr,c)
301# define cacheunget_(f,c) if(fseek(ptr,-2L,SEEK_CUR))Ierror();else cacheget_(c)
302# define Ioffset_type long
303# define Itell(f) ftell(f)
304# define Ifileno(f) fileno(f)
305#endif
306
307/* Print a char, but abort on write error. */
308#define aputc_(c,o) { if (putc(c,o)==EOF) testOerror(o); }
309
310/* Get a character from an RCS file, perhaps copying to a new RCS file. */
311#define GETCeof_(o,c,s) { cachegeteof_(c,s) if (o) aputc_(c,o) }
312#define GETC_(o,c) { cacheget_(c) if (o) aputc_(c,o) }
313
314
315#define WORKMODE(RCSmode, writable) (((RCSmode)&(mode_t)~(S_IWUSR|S_IWGRP|S_IWOTH)) | ((writable)?S_IWUSR:0))
316/* computes mode of working file: same as RCSmode, but write permission */
317/* determined by writable */
318
319
320/* character classes and token codes */
321enum tokens {
322/* classes */ DELIM, DIGIT, IDCHAR, NEWLN, LETTER, Letter,
323 PERIOD, SBEGIN, SPACE, UNKN,
324/* tokens */ COLON, ID, NUM, SEMI, STRING
325};
326
327#define SDELIM '@' /* the actual character is needed for string handling*/
328/* SDELIM must be consistent with ctab[], so that ctab[SDELIM]==SBEGIN.
329 * there should be no overlap among SDELIM, KDELIM, and VDELIM
330 */
331
332#define isdigit(c) (((unsigned)(c)-'0') <= 9) /* faster than ctab[c]==DIGIT */
333
334
335
336
337
338/***************************************
339 * Data structures for the symbol table
340 ***************************************/
341
342/* Buffer of arbitrary data */
343struct buf {
344 char *string;
345 size_t size;
346};
347struct cbuf {
348 char const *string;
349 size_t size;
350};
351
352/* Hash table entry */
353struct hshentry {
354 char const * num; /* pointer to revision number (ASCIZ) */
355 char const * date; /* pointer to date of checkin */
356 char const * author; /* login of person checking in */
357 char const * lockedby; /* who locks the revision */
358 char const * state; /* state of revision (Exp by default) */
359 char const * name; /* name (if any) by which retrieved */
360 struct cbuf log; /* log message requested at checkin */
361 struct branchhead * branches; /* list of first revisions on branches*/
362 struct cbuf ig; /* ignored phrases in admin part */
363 struct cbuf igtext; /* ignored phrases in deltatext part */
364 struct hshentry * next; /* next revision on same branch */
365 struct hshentry * nexthsh; /* next revision with same hash value */
366 long insertlns;/* lines inserted (computed by rlog) */
367 long deletelns;/* lines deleted (computed by rlog) */
368 char selector; /* true if selected, false if deleted */
369};
370
371/* list of hash entries */
372struct hshentries {
373 struct hshentries *rest;
374 struct hshentry *first;
375};
376
377/* list element for branch lists */
378struct branchhead {
379 struct hshentry * hsh;
380 struct branchhead * nextbranch;
381};
382
383/* accesslist element */
384struct access {
385 char const * login;
386 struct access * nextaccess;
387};
388
389/* list element for locks */
390struct rcslock {
391 char const * login;
392 struct hshentry * delta;
393 struct rcslock * nextlock;
394};
395
396/* list element for symbolic names */
397struct assoc {
398 char const * symbol;
399 char const * num;
400 struct assoc * nextassoc;
401};
402
403
404#define mainArgs (argc,argv) int argc; char **argv;
405
406#if RCS_lint
407# define libId(name,rcsid)
408# define mainProg(name,cmd,rcsid) int name mainArgs
409#else
410# define libId(name,rcsid) char const name[] = rcsid;
411# define mainProg(n,c,i) char const Copyright[] = "Copyright 1982,1988,1989 Walter F. Tichy, Purdue CS\nCopyright 1990,1991,1992,1993,1994,1995 Paul Eggert", baseid[] = RCSBASE, cmdid[] = c; libId(n,i) int main P((int,char**)); int main mainArgs
412#endif
413
414/*
415 * Markers for keyword expansion (used in co and ident)
416 * Every byte must have class LETTER or Letter.
417 */
418#define AUTHOR "Author"
419#define DATE "Date"
420#define HEADER "Header"
421#define IDH "Id"
422#define LOCKER "Locker"
423#define LOG "Log"
424#define NAME "Name"
425#define RCSFILE "RCSfile"
426#define REVISION "Revision"
427#define SOURCE "Source"
428#define STATE "State"
429#define FREEBSD "FreeBSD"
430#define keylength 8 /* max length of any of the above keywords */
429#define CVSHEADER "CVSHeader"
430#define keylength 9 /* max length of any of the above keywords */
431
432enum markers { Nomatch, Author, Date, Header, Id,
431
432enum markers { Nomatch, Author, Date, Header, Id,
433 Locker, Log, Name, RCSfile, Revision, Source, State, FreeBSD };
433 Locker, Log, Name, RCSfile, Revision, Source, State, CVSHeader,
434 LocalId };
434 /* This must be in the same order as rcskeys.c's Keyword[] array. */
435
436#define DELNUMFORM "\n\n%s\n%s\n"
437/* used by putdtext and scanlogtext */
438
439#define EMPTYLOG "*** empty log message ***" /* used by ci and rlog */
440
441/* main program */
442extern char const cmdid[];
443void exiterr P((void)) exiting;
444
445/* merge */
446int merge P((int,char const*,char const*const[3],char const*const[3]));
447
448/* rcsedit */
449#define ciklogsize 23 /* sizeof("checked in with -k by ") */
450extern FILE *fcopy;
451extern char const *resultname;
452extern char const ciklog[ciklogsize];
453extern int locker_expansion;
454RILE *rcswriteopen P((struct buf*,struct stat*,int));
455char const *makedirtemp P((int));
456char const *getcaller P((void));
457int addlock P((struct hshentry*,int));
458int addsymbol P((char const*,char const*,int));
459int checkaccesslist P((void));
460int chnamemod P((FILE**,char const*,char const*,int,mode_t,time_t));
461int donerewrite P((int,time_t));
462int dorewrite P((int,int));
463int expandline P((RILE*,FILE*,struct hshentry const*,int,FILE*,int));
464int findlock P((int,struct hshentry**));
465int setmtime P((char const*,time_t));
466void ORCSclose P((void));
467void ORCSerror P((void));
468void copystring P((void));
469void dirtempunlink P((void));
470void enterstring P((void));
471void finishedit P((struct hshentry const*,FILE*,int));
472void keepdirtemp P((char const*));
473void openfcopy P((FILE*));
474void snapshotedit P((FILE*));
475void xpandstring P((struct hshentry const*));
476#if has_NFS || bad_unlink
477 int un_link P((char const*));
478#else
479# define un_link(s) unlink(s)
480#endif
481#if large_memory
482 void edit_string P((void));
483# define editstring(delta) edit_string()
484#else
485 void editstring P((struct hshentry const*));
486#endif
487
488/* rcsfcmp */
489int rcsfcmp P((RILE*,struct stat const*,char const*,struct hshentry const*));
490
491/* rcsfnms */
492#define bufautobegin(b) clear_buf(b)
493#define clear_buf(b) (VOID ((b)->string = 0, (b)->size = 0))
494extern FILE *workstdout;
495extern char *workname;
496extern char const *RCSname;
497extern char const *suffixes;
498extern int fdlock;
499extern struct stat RCSstat;
500RILE *rcsreadopen P((struct buf*,struct stat*,int));
501char *bufenlarge P((struct buf*,char const**));
502char const *basefilename P((char const*));
503char const *getfullRCSname P((void));
435 /* This must be in the same order as rcskeys.c's Keyword[] array. */
436
437#define DELNUMFORM "\n\n%s\n%s\n"
438/* used by putdtext and scanlogtext */
439
440#define EMPTYLOG "*** empty log message ***" /* used by ci and rlog */
441
442/* main program */
443extern char const cmdid[];
444void exiterr P((void)) exiting;
445
446/* merge */
447int merge P((int,char const*,char const*const[3],char const*const[3]));
448
449/* rcsedit */
450#define ciklogsize 23 /* sizeof("checked in with -k by ") */
451extern FILE *fcopy;
452extern char const *resultname;
453extern char const ciklog[ciklogsize];
454extern int locker_expansion;
455RILE *rcswriteopen P((struct buf*,struct stat*,int));
456char const *makedirtemp P((int));
457char const *getcaller P((void));
458int addlock P((struct hshentry*,int));
459int addsymbol P((char const*,char const*,int));
460int checkaccesslist P((void));
461int chnamemod P((FILE**,char const*,char const*,int,mode_t,time_t));
462int donerewrite P((int,time_t));
463int dorewrite P((int,int));
464int expandline P((RILE*,FILE*,struct hshentry const*,int,FILE*,int));
465int findlock P((int,struct hshentry**));
466int setmtime P((char const*,time_t));
467void ORCSclose P((void));
468void ORCSerror P((void));
469void copystring P((void));
470void dirtempunlink P((void));
471void enterstring P((void));
472void finishedit P((struct hshentry const*,FILE*,int));
473void keepdirtemp P((char const*));
474void openfcopy P((FILE*));
475void snapshotedit P((FILE*));
476void xpandstring P((struct hshentry const*));
477#if has_NFS || bad_unlink
478 int un_link P((char const*));
479#else
480# define un_link(s) unlink(s)
481#endif
482#if large_memory
483 void edit_string P((void));
484# define editstring(delta) edit_string()
485#else
486 void editstring P((struct hshentry const*));
487#endif
488
489/* rcsfcmp */
490int rcsfcmp P((RILE*,struct stat const*,char const*,struct hshentry const*));
491
492/* rcsfnms */
493#define bufautobegin(b) clear_buf(b)
494#define clear_buf(b) (VOID ((b)->string = 0, (b)->size = 0))
495extern FILE *workstdout;
496extern char *workname;
497extern char const *RCSname;
498extern char const *suffixes;
499extern int fdlock;
500extern struct stat RCSstat;
501RILE *rcsreadopen P((struct buf*,struct stat*,int));
502char *bufenlarge P((struct buf*,char const**));
503char const *basefilename P((char const*));
504char const *getfullRCSname P((void));
505char const *getfullCVSname P((void));
504char const *maketemp P((int));
505char const *rcssuffix P((char const*));
506int pairnames P((int,char**,RILE*(*)P((struct buf*,struct stat*,int)),int,int));
507struct cbuf bufremember P((struct buf*,size_t));
508void bufalloc P((struct buf*,size_t));
509void bufautoend P((struct buf*));
510void bufrealloc P((struct buf*,size_t));
511void bufscat P((struct buf*,char const*));
512void bufscpy P((struct buf*,char const*));
513void tempunlink P((void));
514
515/* rcsgen */
516extern int interactiveflag;
517extern struct buf curlogbuf;
518char const *buildrevision P((struct hshentries const*,struct hshentry*,FILE*,int));
519int getcstdin P((void));
520int putdtext P((struct hshentry const*,char const*,FILE*,int));
521int ttystdin P((void));
522int yesorno P((int,char const*,...)) printf_string(2,3);
523struct cbuf cleanlogmsg P((char*,size_t));
524struct cbuf getsstdin P((char const*,char const*,char const*,struct buf*));
525void putdesc P((int,char*));
526void putdftext P((struct hshentry const*,RILE*,FILE*,int));
527
528/* rcskeep */
529extern int prevkeys;
530extern struct buf prevauthor, prevdate, prevname, prevrev, prevstate;
531int getoldkeys P((RILE*));
532
533/* rcskeys */
506char const *maketemp P((int));
507char const *rcssuffix P((char const*));
508int pairnames P((int,char**,RILE*(*)P((struct buf*,struct stat*,int)),int,int));
509struct cbuf bufremember P((struct buf*,size_t));
510void bufalloc P((struct buf*,size_t));
511void bufautoend P((struct buf*));
512void bufrealloc P((struct buf*,size_t));
513void bufscat P((struct buf*,char const*));
514void bufscpy P((struct buf*,char const*));
515void tempunlink P((void));
516
517/* rcsgen */
518extern int interactiveflag;
519extern struct buf curlogbuf;
520char const *buildrevision P((struct hshentries const*,struct hshentry*,FILE*,int));
521int getcstdin P((void));
522int putdtext P((struct hshentry const*,char const*,FILE*,int));
523int ttystdin P((void));
524int yesorno P((int,char const*,...)) printf_string(2,3);
525struct cbuf cleanlogmsg P((char*,size_t));
526struct cbuf getsstdin P((char const*,char const*,char const*,struct buf*));
527void putdesc P((int,char*));
528void putdftext P((struct hshentry const*,RILE*,FILE*,int));
529
530/* rcskeep */
531extern int prevkeys;
532extern struct buf prevauthor, prevdate, prevname, prevrev, prevstate;
533int getoldkeys P((RILE*));
534
535/* rcskeys */
534extern char const *const Keyword[];
536extern char const *Keyword[];
537extern enum markers LocalIdMode;
535enum markers trymatch P((char const*));
538enum markers trymatch P((char const*));
539void setRCSLocalId(char const *);
540void setIncExc(char const *);
536
537/* rcslex */
538extern FILE *foutptr;
539extern FILE *frewrite;
540extern RILE *finptr;
541extern char const *NextString;
542extern enum tokens nexttok;
543extern int hshenter;
544extern int nerror;
545extern int nextc;
546extern int quietflag;
547extern long rcsline;
548char const *getid P((void));
549void efaterror P((char const*)) exiting;
550void enfaterror P((int,char const*)) exiting;
551void fatcleanup P((int)) exiting;
552void faterror P((char const*,...)) printf_string_exiting(1,2);
553void fatserror P((char const*,...)) printf_string_exiting(1,2);
554void rcsfaterror P((char const*,...)) printf_string_exiting(1,2);
555void Ieof P((void)) exiting;
556void Ierror P((void)) exiting;
557void Oerror P((void)) exiting;
558char *checkid P((char*,int));
559char *checksym P((char*,int));
560int eoflex P((void));
561int getkeyopt P((char const*));
562int getlex P((enum tokens));
563struct cbuf getphrases P((char const*));
564struct cbuf savestring P((struct buf*));
565struct hshentry *getnum P((void));
566void Ifclose P((RILE*));
567void Izclose P((RILE**));
568void Lexinit P((void));
569void Ofclose P((FILE*));
570void Orewind P((FILE*));
571void Ozclose P((FILE**));
572void aflush P((FILE*));
573void afputc P((int,FILE*));
574void aprintf P((FILE*,char const*,...)) printf_string(2,3);
575void aputs P((char const*,FILE*));
576void checksid P((char*));
577void checkssym P((char*));
578void diagnose P((char const*,...)) printf_string(1,2);
579void eerror P((char const*));
580void eflush P((void));
581void enerror P((int,char const*));
582void error P((char const*,...)) printf_string(1,2);
583void fvfprintf P((FILE*,char const*,va_list));
584void getkey P((char const*));
585void getkeystring P((char const*));
586void nextlex P((void));
587void oflush P((void));
588void printstring P((void));
589void readstring P((void));
590void redefined P((int));
591void rcserror P((char const*,...)) printf_string(1,2);
592void rcswarn P((char const*,...)) printf_string(1,2);
593void testIerror P((FILE*));
594void testOerror P((FILE*));
595void warn P((char const*,...)) printf_string(1,2);
596void warnignore P((void));
597void workerror P((char const*,...)) printf_string(1,2);
598void workwarn P((char const*,...)) printf_string(1,2);
599#if has_madvise && has_mmap && large_memory
600 void advise_access P((RILE*,int));
601# define if_advise_access(p,f,advice) if (p) advise_access(f,advice)
602#else
603# define advise_access(f,advice)
604# define if_advise_access(p,f,advice)
605#endif
606#if large_memory && maps_memory
607 RILE *I_open P((char const*,struct stat*));
608# define Iopen(f,m,s) I_open(f,s)
609#else
610 RILE *Iopen P((char const*,char const*,struct stat*));
611#endif
612#if !large_memory
613 void testIeof P((FILE*));
614 void Irewind P((RILE*));
615#endif
616
617/* rcsmap */
618extern enum tokens const ctab[];
619
620/* rcsrev */
621char *partialno P((struct buf*,char const*,int));
622char const *namedrev P((char const*,struct hshentry*));
623char const *tiprev P((void));
624int cmpdate P((char const*,char const*));
625int cmpnum P((char const*,char const*));
626int cmpnumfld P((char const*,char const*,int));
627int compartial P((char const*,char const*,int));
628int expandsym P((char const*,struct buf*));
629int fexpandsym P((char const*,struct buf*,RILE*));
630struct hshentry *genrevs P((char const*,char const*,char const*,char const*,struct hshentries**));
631int countnumflds P((char const*));
632void getbranchno P((char const*,struct buf*));
633
634/* rcssyn */
635/* These expand modes must agree with Expand_names[] in rcssyn.c. */
636#define KEYVAL_EXPAND 0 /* -kkv `$Keyword: value $' */
637#define KEYVALLOCK_EXPAND 1 /* -kkvl `$Keyword: value locker $' */
638#define KEY_EXPAND 2 /* -kk `$Keyword$' */
639#define VAL_EXPAND 3 /* -kv `value' */
640#define OLD_EXPAND 4 /* -ko use old string, omitting expansion */
641#define BINARY_EXPAND 5 /* -kb like -ko, but use binary mode I/O */
642#define MIN_UNEXPAND OLD_EXPAND /* min value for no logical expansion */
643#define MIN_UNCHANGED_EXPAND (OPEN_O_BINARY ? BINARY_EXPAND : OLD_EXPAND)
644 /* min value guaranteed to yield an identical file */
645struct diffcmd {
646 long
647 line1, /* number of first line */
648 nlines, /* number of lines affected */
649 adprev, /* previous 'a' line1+1 or 'd' line1 */
650 dafter; /* sum of previous 'd' line1 and previous 'd' nlines */
651};
652extern char const * Dbranch;
653extern struct access * AccessList;
654extern struct assoc * Symbols;
655extern struct cbuf Comment;
656extern struct cbuf Ignored;
657extern struct rcslock *Locks;
658extern struct hshentry * Head;
659extern int Expand;
660extern int StrictLocks;
661extern int TotalDeltas;
662extern char const *const expand_names[];
663extern char const
664 Kaccess[], Kauthor[], Kbranch[], Kcomment[],
665 Kdate[], Kdesc[], Kexpand[], Khead[], Klocks[], Klog[],
666 Knext[], Kstate[], Kstrict[], Ksymbols[], Ktext[];
667void unexpected_EOF P((void)) exiting;
668int getdiffcmd P((RILE*,int,FILE*,struct diffcmd*));
669int str2expmode P((char const*));
670void getadmin P((void));
671void getdesc P((int));
672void gettree P((void));
673void ignorephrases P((char const*));
674void initdiffcmd P((struct diffcmd*));
675void putadmin P((void));
676void putstring P((FILE*,int,struct cbuf,int));
677void puttree P((struct hshentry const*,FILE*));
678
679/* rcstime */
680#define zonelenmax 9 /* maxiumum length of time zone string, e.g. "+12:34:56" */
681char const *date2str P((char const[datesize],char[datesize + zonelenmax]));
682time_t date2time P((char const[datesize]));
683void str2date P((char const*,char[datesize]));
684void time2date P((time_t,char[datesize]));
685void zone_set P((char const*));
686
687/* rcsutil */
688extern int RCSversion;
689FILE *fopenSafer P((char const*,char const*));
690char *cgetenv P((char const*));
691char *fstr_save P((char const*));
692char *str_save P((char const*));
693char const *getusername P((int));
694int fdSafer P((int));
695int getRCSINIT P((int,char**,char***));
696int run P((int,char const*,...));
697int runv P((int,char const*,char const**));
698malloc_type fremember P((malloc_type));
699malloc_type ftestalloc P((size_t));
700malloc_type testalloc P((size_t));
701malloc_type testrealloc P((malloc_type,size_t));
702#define ftalloc(T) ftnalloc(T,1)
703#define talloc(T) tnalloc(T,1)
704#if RCS_lint
705 extern malloc_type lintalloc;
706# define ftnalloc(T,n) (lintalloc = ftestalloc(sizeof(T)*(n)), (T*)0)
707# define tnalloc(T,n) (lintalloc = testalloc(sizeof(T)*(n)), (T*)0)
708# define trealloc(T,p,n) (lintalloc = testrealloc((malloc_type)0, sizeof(T)*(n)), p)
709# define tfree(p)
710#else
711# define ftnalloc(T,n) ((T*) ftestalloc(sizeof(T)*(n)))
712# define tnalloc(T,n) ((T*) testalloc(sizeof(T)*(n)))
713# define trealloc(T,p,n) ((T*) testrealloc((malloc_type)(p), sizeof(T)*(n)))
714# define tfree(p) free((malloc_type)(p))
715#endif
716time_t now P((void));
717void awrite P((char const*,size_t,FILE*));
718void fastcopy P((RILE*,FILE*));
719void ffree P((void));
720void ffree1 P((char const*));
721void setRCSversion P((char const*));
722#if has_signal
723 void catchints P((void));
724 void ignoreints P((void));
725 void restoreints P((void));
726#else
727# define catchints()
728# define ignoreints()
729# define restoreints()
730#endif
731#if has_mmap && large_memory
732# if has_NFS && mmap_signal
733 void catchmmapints P((void));
734 void readAccessFilenameBuffer P((char const*,unsigned char const*));
735# else
736# define catchmmapints()
737# endif
738#endif
739#if has_getuid
740 uid_t ruid P((void));
741# define myself(u) ((u) == ruid())
742#else
743# define myself(u) true
744#endif
745#if has_setuid
746 uid_t euid P((void));
747 void nosetid P((void));
748 void seteid P((void));
749 void setrid P((void));
750#else
751# define nosetid()
752# define seteid()
753# define setrid()
754#endif
755
756/* version */
757extern char const RCS_version_string[];
541
542/* rcslex */
543extern FILE *foutptr;
544extern FILE *frewrite;
545extern RILE *finptr;
546extern char const *NextString;
547extern enum tokens nexttok;
548extern int hshenter;
549extern int nerror;
550extern int nextc;
551extern int quietflag;
552extern long rcsline;
553char const *getid P((void));
554void efaterror P((char const*)) exiting;
555void enfaterror P((int,char const*)) exiting;
556void fatcleanup P((int)) exiting;
557void faterror P((char const*,...)) printf_string_exiting(1,2);
558void fatserror P((char const*,...)) printf_string_exiting(1,2);
559void rcsfaterror P((char const*,...)) printf_string_exiting(1,2);
560void Ieof P((void)) exiting;
561void Ierror P((void)) exiting;
562void Oerror P((void)) exiting;
563char *checkid P((char*,int));
564char *checksym P((char*,int));
565int eoflex P((void));
566int getkeyopt P((char const*));
567int getlex P((enum tokens));
568struct cbuf getphrases P((char const*));
569struct cbuf savestring P((struct buf*));
570struct hshentry *getnum P((void));
571void Ifclose P((RILE*));
572void Izclose P((RILE**));
573void Lexinit P((void));
574void Ofclose P((FILE*));
575void Orewind P((FILE*));
576void Ozclose P((FILE**));
577void aflush P((FILE*));
578void afputc P((int,FILE*));
579void aprintf P((FILE*,char const*,...)) printf_string(2,3);
580void aputs P((char const*,FILE*));
581void checksid P((char*));
582void checkssym P((char*));
583void diagnose P((char const*,...)) printf_string(1,2);
584void eerror P((char const*));
585void eflush P((void));
586void enerror P((int,char const*));
587void error P((char const*,...)) printf_string(1,2);
588void fvfprintf P((FILE*,char const*,va_list));
589void getkey P((char const*));
590void getkeystring P((char const*));
591void nextlex P((void));
592void oflush P((void));
593void printstring P((void));
594void readstring P((void));
595void redefined P((int));
596void rcserror P((char const*,...)) printf_string(1,2);
597void rcswarn P((char const*,...)) printf_string(1,2);
598void testIerror P((FILE*));
599void testOerror P((FILE*));
600void warn P((char const*,...)) printf_string(1,2);
601void warnignore P((void));
602void workerror P((char const*,...)) printf_string(1,2);
603void workwarn P((char const*,...)) printf_string(1,2);
604#if has_madvise && has_mmap && large_memory
605 void advise_access P((RILE*,int));
606# define if_advise_access(p,f,advice) if (p) advise_access(f,advice)
607#else
608# define advise_access(f,advice)
609# define if_advise_access(p,f,advice)
610#endif
611#if large_memory && maps_memory
612 RILE *I_open P((char const*,struct stat*));
613# define Iopen(f,m,s) I_open(f,s)
614#else
615 RILE *Iopen P((char const*,char const*,struct stat*));
616#endif
617#if !large_memory
618 void testIeof P((FILE*));
619 void Irewind P((RILE*));
620#endif
621
622/* rcsmap */
623extern enum tokens const ctab[];
624
625/* rcsrev */
626char *partialno P((struct buf*,char const*,int));
627char const *namedrev P((char const*,struct hshentry*));
628char const *tiprev P((void));
629int cmpdate P((char const*,char const*));
630int cmpnum P((char const*,char const*));
631int cmpnumfld P((char const*,char const*,int));
632int compartial P((char const*,char const*,int));
633int expandsym P((char const*,struct buf*));
634int fexpandsym P((char const*,struct buf*,RILE*));
635struct hshentry *genrevs P((char const*,char const*,char const*,char const*,struct hshentries**));
636int countnumflds P((char const*));
637void getbranchno P((char const*,struct buf*));
638
639/* rcssyn */
640/* These expand modes must agree with Expand_names[] in rcssyn.c. */
641#define KEYVAL_EXPAND 0 /* -kkv `$Keyword: value $' */
642#define KEYVALLOCK_EXPAND 1 /* -kkvl `$Keyword: value locker $' */
643#define KEY_EXPAND 2 /* -kk `$Keyword$' */
644#define VAL_EXPAND 3 /* -kv `value' */
645#define OLD_EXPAND 4 /* -ko use old string, omitting expansion */
646#define BINARY_EXPAND 5 /* -kb like -ko, but use binary mode I/O */
647#define MIN_UNEXPAND OLD_EXPAND /* min value for no logical expansion */
648#define MIN_UNCHANGED_EXPAND (OPEN_O_BINARY ? BINARY_EXPAND : OLD_EXPAND)
649 /* min value guaranteed to yield an identical file */
650struct diffcmd {
651 long
652 line1, /* number of first line */
653 nlines, /* number of lines affected */
654 adprev, /* previous 'a' line1+1 or 'd' line1 */
655 dafter; /* sum of previous 'd' line1 and previous 'd' nlines */
656};
657extern char const * Dbranch;
658extern struct access * AccessList;
659extern struct assoc * Symbols;
660extern struct cbuf Comment;
661extern struct cbuf Ignored;
662extern struct rcslock *Locks;
663extern struct hshentry * Head;
664extern int Expand;
665extern int StrictLocks;
666extern int TotalDeltas;
667extern char const *const expand_names[];
668extern char const
669 Kaccess[], Kauthor[], Kbranch[], Kcomment[],
670 Kdate[], Kdesc[], Kexpand[], Khead[], Klocks[], Klog[],
671 Knext[], Kstate[], Kstrict[], Ksymbols[], Ktext[];
672void unexpected_EOF P((void)) exiting;
673int getdiffcmd P((RILE*,int,FILE*,struct diffcmd*));
674int str2expmode P((char const*));
675void getadmin P((void));
676void getdesc P((int));
677void gettree P((void));
678void ignorephrases P((char const*));
679void initdiffcmd P((struct diffcmd*));
680void putadmin P((void));
681void putstring P((FILE*,int,struct cbuf,int));
682void puttree P((struct hshentry const*,FILE*));
683
684/* rcstime */
685#define zonelenmax 9 /* maxiumum length of time zone string, e.g. "+12:34:56" */
686char const *date2str P((char const[datesize],char[datesize + zonelenmax]));
687time_t date2time P((char const[datesize]));
688void str2date P((char const*,char[datesize]));
689void time2date P((time_t,char[datesize]));
690void zone_set P((char const*));
691
692/* rcsutil */
693extern int RCSversion;
694FILE *fopenSafer P((char const*,char const*));
695char *cgetenv P((char const*));
696char *fstr_save P((char const*));
697char *str_save P((char const*));
698char const *getusername P((int));
699int fdSafer P((int));
700int getRCSINIT P((int,char**,char***));
701int run P((int,char const*,...));
702int runv P((int,char const*,char const**));
703malloc_type fremember P((malloc_type));
704malloc_type ftestalloc P((size_t));
705malloc_type testalloc P((size_t));
706malloc_type testrealloc P((malloc_type,size_t));
707#define ftalloc(T) ftnalloc(T,1)
708#define talloc(T) tnalloc(T,1)
709#if RCS_lint
710 extern malloc_type lintalloc;
711# define ftnalloc(T,n) (lintalloc = ftestalloc(sizeof(T)*(n)), (T*)0)
712# define tnalloc(T,n) (lintalloc = testalloc(sizeof(T)*(n)), (T*)0)
713# define trealloc(T,p,n) (lintalloc = testrealloc((malloc_type)0, sizeof(T)*(n)), p)
714# define tfree(p)
715#else
716# define ftnalloc(T,n) ((T*) ftestalloc(sizeof(T)*(n)))
717# define tnalloc(T,n) ((T*) testalloc(sizeof(T)*(n)))
718# define trealloc(T,p,n) ((T*) testrealloc((malloc_type)(p), sizeof(T)*(n)))
719# define tfree(p) free((malloc_type)(p))
720#endif
721time_t now P((void));
722void awrite P((char const*,size_t,FILE*));
723void fastcopy P((RILE*,FILE*));
724void ffree P((void));
725void ffree1 P((char const*));
726void setRCSversion P((char const*));
727#if has_signal
728 void catchints P((void));
729 void ignoreints P((void));
730 void restoreints P((void));
731#else
732# define catchints()
733# define ignoreints()
734# define restoreints()
735#endif
736#if has_mmap && large_memory
737# if has_NFS && mmap_signal
738 void catchmmapints P((void));
739 void readAccessFilenameBuffer P((char const*,unsigned char const*));
740# else
741# define catchmmapints()
742# endif
743#endif
744#if has_getuid
745 uid_t ruid P((void));
746# define myself(u) ((u) == ruid())
747#else
748# define myself(u) true
749#endif
750#if has_setuid
751 uid_t euid P((void));
752 void nosetid P((void));
753 void seteid P((void));
754 void setrid P((void));
755#else
756# define nosetid()
757# define seteid()
758# define setrid()
759#endif
760
761/* version */
762extern char const RCS_version_string[];