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