rcsbase.h revision 9
19Sjkh
29Sjkh/*
39Sjkh *                     RCS common definitions and data structures
49Sjkh */
59Sjkh#define RCSBASE "$Id: rcsbase.h,v 5.11 1991/10/07 17:32:46 eggert Exp $"
69Sjkh
79Sjkh/* Copyright (C) 1982, 1988, 1989 Walter Tichy
89Sjkh   Copyright 1990, 1991 by Paul Eggert
99Sjkh   Distributed under license by the Free Software Foundation, Inc.
109Sjkh
119SjkhThis file is part of RCS.
129Sjkh
139SjkhRCS is free software; you can redistribute it and/or modify
149Sjkhit under the terms of the GNU General Public License as published by
159Sjkhthe Free Software Foundation; either version 2, or (at your option)
169Sjkhany later version.
179Sjkh
189SjkhRCS is distributed in the hope that it will be useful,
199Sjkhbut WITHOUT ANY WARRANTY; without even the implied warranty of
209SjkhMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
219SjkhGNU General Public License for more details.
229Sjkh
239SjkhYou should have received a copy of the GNU General Public License
249Sjkhalong with RCS; see the file COPYING.  If not, write to
259Sjkhthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
269Sjkh
279SjkhReport problems and direct all questions to:
289Sjkh
299Sjkh    rcs-bugs@cs.purdue.edu
309Sjkh
319Sjkh*/
329Sjkh
339Sjkh
349Sjkh
359Sjkh/*****************************************************************************
369Sjkh * INSTRUCTIONS:
379Sjkh * =============
389Sjkh * See the Makefile for how to define C preprocessor symbols.
399Sjkh * If you need to change the comment leaders, update the table comtable[]
409Sjkh * in rcsfnms.c. (This can wait until you know what a comment leader is.)
419Sjkh *****************************************************************************
429Sjkh */
439Sjkh
449Sjkh
459Sjkh/* $Log: rcsbase.h,v $
469Sjkh * Revision 5.11  1991/10/07  17:32:46  eggert
479Sjkh * Support piece tables even if !has_mmap.
489Sjkh *
499Sjkh * Revision 5.10  1991/09/24  00:28:39  eggert
509Sjkh * Remove unexported functions.
519Sjkh *
529Sjkh * Revision 5.9  1991/08/19  03:13:55  eggert
539Sjkh * Add piece tables and other tuneups, and NFS workarounds.
549Sjkh *
559Sjkh * Revision 5.8  1991/04/21  11:58:20  eggert
569Sjkh * Add -x, RCSINIT, MS-DOS support.
579Sjkh *
589Sjkh * Revision 5.7  1991/02/28  19:18:50  eggert
599Sjkh * Try setuid() if seteuid() doesn't work.
609Sjkh *
619Sjkh * Revision 5.6  1991/02/26  17:48:37  eggert
629Sjkh * Support new link behavior.  Move ANSI C / Posix declarations into conf.sh.
639Sjkh *
649Sjkh * Revision 5.5  1990/12/04  05:18:43  eggert
659Sjkh * Use -I for prompts and -q for diagnostics.
669Sjkh *
679Sjkh * Revision 5.4  1990/11/01  05:03:35  eggert
689Sjkh * Don't assume that builtins are functions; they may be macros.
699Sjkh * Permit arbitrary data in logs.
709Sjkh *
719Sjkh * Revision 5.3  1990/09/26  23:36:58  eggert
729Sjkh * Port wait() to non-Posix ANSI C hosts.
739Sjkh *
749Sjkh * Revision 5.2  1990/09/04  08:02:20  eggert
759Sjkh * Don't redefine NAME_MAX, PATH_MAX.
769Sjkh * Improve incomplete line handling.  Standardize yes-or-no procedure.
779Sjkh *
789Sjkh * Revision 5.1  1990/08/29  07:13:53  eggert
799Sjkh * Add -kkvl.  Fix type typos exposed by porting.  Clean old log messages too.
809Sjkh *
819Sjkh * Revision 5.0  1990/08/22  08:12:44  eggert
829Sjkh * Adjust ANSI C / Posix support.  Add -k, -V, setuid.  Don't call access().
839Sjkh * Remove compile-time limits; use malloc instead.
849Sjkh * Ansify and Posixate.  Add support for ISO 8859.
859Sjkh * Remove snoop and v2 support.
869Sjkh *
879Sjkh * Revision 4.9  89/05/01  15:17:14  narten
889Sjkh * botched previous USG fix
899Sjkh *
909Sjkh * Revision 4.8  89/05/01  14:53:05  narten
919Sjkh * changed #include <strings.h> -> string.h for USG systems.
929Sjkh *
939Sjkh * Revision 4.7  88/11/08  15:58:45  narten
949Sjkh * removed defs for functions loaded from libraries
959Sjkh *
969Sjkh * Revision 4.6  88/08/09  19:12:36  eggert
979Sjkh * Shrink stdio code size; remove lint; permit -Dhshsize=nn.
989Sjkh *
999Sjkh * Revision 4.5  87/12/18  17:06:41  narten
1009Sjkh * made removed BSD ifdef, now uses V4_2BSD
1019Sjkh *
1029Sjkh * Revision 4.4  87/10/18  10:29:49  narten
1039Sjkh * Updating version numbers
1049Sjkh * Changes relative to 1.1 are actually relative to 4.2
1059Sjkh *
1069Sjkh * Revision 1.3  87/09/24  14:02:25  narten
1079Sjkh * changes for lint
1089Sjkh *
1099Sjkh * Revision 1.2  87/03/27  14:22:02  jenkins
1109Sjkh * Port to suns
1119Sjkh *
1129Sjkh * Revision 4.2  83/12/20  16:04:20  wft
1139Sjkh * merged 3.6.1.1 and 4.1 (SMALLOG, logsize).
1149Sjkh * moved setting of STRICT_LOCKING to Makefile.
1159Sjkh * changed DOLLAR to UNKN (conflict with KDELIM).
1169Sjkh *
1179Sjkh * Revision 4.1  83/05/04  09:12:41  wft
1189Sjkh * Added markers Id and RCSfile.
1199Sjkh * Added Dbranch for default branches.
1209Sjkh *
1219Sjkh * Revision 3.6.1.1  83/12/02  21:56:22  wft
1229Sjkh * Increased logsize, added macro SMALLOG.
1239Sjkh *
1249Sjkh * Revision 3.6  83/01/15  16:43:28  wft
1259Sjkh * 4.2 prerelease
1269Sjkh *
1279Sjkh * Revision 3.6  83/01/15  16:43:28  wft
1289Sjkh * Replaced dbm.h with BYTESIZ, fixed definition of rindex().
1299Sjkh * Added variants of NCPFN and NCPPN for bsd 4.2, selected by defining V4_2BSD.
1309Sjkh * Added macro DELNUMFORM to have uniform format for printing delta text nodes.
1319Sjkh * Added macro DELETE to mark deleted deltas.
1329Sjkh *
1339Sjkh * Revision 3.5  82/12/10  12:16:56  wft
1349Sjkh * Added two forms of DATEFORM, one using %02d, the other %.2d.
1359Sjkh *
1369Sjkh * Revision 3.4  82/12/04  20:01:25  wft
1379Sjkh * added LOCKER, Locker, and USG (redefinition of rindex).
1389Sjkh *
1399Sjkh * Revision 3.3  82/12/03  12:22:04  wft
1409Sjkh * Added dbm.h, stdio.h, RCSBASE, RCSSEP, RCSSUF, WORKMODE, TMPFILE3,
1419Sjkh * PRINTDATE, PRINTTIME, map, and ctab; removed Suffix. Redefined keyvallength
1429Sjkh * using NCPPN. Changed putc() to abort on write error.
1439Sjkh *
1449Sjkh * Revision 3.2  82/10/18  15:03:52  wft
1459Sjkh * added macro STRICT_LOCKING, removed RCSUMASK.
1469Sjkh * renamed JOINFILE[1,2] to JOINFIL[1,2].
1479Sjkh *
1489Sjkh * Revision 3.1  82/10/11  19:41:17  wft
1499Sjkh * removed NBPW, NBPC, NCPW.
1509Sjkh * added typdef int void to aid compiling
1519Sjkh */
1529Sjkh
1539Sjkh
1549Sjkh#include "conf.h"
1559Sjkh
1569Sjkh
1579Sjkh#define EXIT_TROUBLE DIFF_TROUBLE
1589Sjkh
1599Sjkh#ifdef PATH_MAX
1609Sjkh#	define SIZEABLE_PATH PATH_MAX /* size of a large path; not a hard limit */
1619Sjkh#else
1629Sjkh#	define SIZEABLE_PATH _POSIX_PATH_MAX
1639Sjkh#endif
1649Sjkh
1659Sjkh/* for traditional C hosts with unusual size arguments */
1669Sjkh#define Fread(p,s,n,f)  fread(p, (freadarg_type)(s), (freadarg_type)(n), f)
1679Sjkh#define Fwrite(p,s,n,f)  fwrite(p, (freadarg_type)(s), (freadarg_type)(n), f)
1689Sjkh
1699Sjkh
1709Sjkh/*
1719Sjkh * Parameters
1729Sjkh */
1739Sjkh
1749Sjkh/* backwards compatibility with old versions of RCS */
1759Sjkh#define VERSION_min 3		/* old output RCS format supported */
1769Sjkh#define VERSION_max 5		/* newest output RCS format supported */
1779Sjkh#ifndef VERSION_DEFAULT		/* default RCS output format */
1789Sjkh#	define VERSION_DEFAULT VERSION_max
1799Sjkh#endif
1809Sjkh#define VERSION(n) ((n) - VERSION_DEFAULT) /* internally, 0 is the default */
1819Sjkh
1829Sjkh#ifndef STRICT_LOCKING
1839Sjkh#define STRICT_LOCKING 1
1849Sjkh#endif
1859Sjkh			      /* 0 sets the default locking to non-strict;  */
1869Sjkh                              /* used in experimental environments.         */
1879Sjkh                              /* 1 sets the default locking to strict;      */
1889Sjkh                              /* used in production environments.           */
1899Sjkh
1909Sjkh#define yearlength	   16 /* (good through AD 9,999,999,999,999,999)    */
1919Sjkh#define datesize (yearlength+16) /* size of output of DATEFORM		    */
1929Sjkh#define joinlength         20 /* number of joined revisions permitted       */
1939Sjkh#define RCSTMPPREFIX '_' /* prefix for temp files in working dir  */
1949Sjkh#define KDELIM            '$' /* delimiter for keywords                     */
1959Sjkh#define VDELIM            ':' /* separates keywords from values             */
1969Sjkh#define DEFAULTSTATE    "Exp" /* default state of revisions                 */
1979Sjkh
1989Sjkh
1999Sjkh
2009Sjkh#define true     1
2019Sjkh#define false    0
2029Sjkh#define nil      0
2039Sjkh
2049Sjkh
2059Sjkh/*
2069Sjkh * RILE - readonly file
2079Sjkh * declarecache; - declares local cache for RILE variable(s)
2089Sjkh * setupcache - sets up the local RILE cache, but does not initialize it
2099Sjkh * cache, uncache - caches and uncaches the local RILE;
2109Sjkh *	(uncache,cache) is needed around functions that advance the RILE pointer
2119Sjkh * Igeteof(f,c,s) - get a char c from f, executing statement s at EOF
2129Sjkh * cachegeteof(c,s) - Igeteof applied to the local RILE
2139Sjkh * Iget(f,c) - like Igeteof, except EOF is an error
2149Sjkh * cacheget(c) - Iget applied to the local RILE
2159Sjkh * Ifileno, Irewind, Iseek, Itell - analogs to stdio routines
2169Sjkh */
2179Sjkh
2189Sjkh#if large_memory
2199Sjkh	typedef unsigned char const *Iptr_type;
2209Sjkh	typedef struct {
2219Sjkh		Iptr_type ptr, lim;
2229Sjkh		unsigned char *base; /* for lint, not Iptr_type even if has_mmap */
2239Sjkh#		if has_mmap
2249Sjkh#			define Ifileno(f) ((f)->fd)
2259Sjkh			int fd;
2269Sjkh#		else
2279Sjkh#			define Ifileno(f) fileno((f)->stream)
2289Sjkh			FILE *stream;
2299Sjkh			unsigned char *readlim;
2309Sjkh#		endif
2319Sjkh	} RILE;
2329Sjkh#	if has_mmap
2339Sjkh#		define declarecache register Iptr_type ptr, lim
2349Sjkh#		define setupcache(f) (lim = (f)->lim)
2359Sjkh#		define Igeteof(f,c,s) if ((f)->ptr==(f)->lim) s else (c)= *(f)->ptr++
2369Sjkh#		define cachegeteof(c,s) if (ptr==lim) s else (c)= *ptr++
2379Sjkh#	else
2389Sjkh#		define declarecache register Iptr_type ptr; register RILE *rRILE
2399Sjkh#		define setupcache(f) (rRILE = (f))
2409Sjkh#		define Igeteof(f,c,s) if ((f)->ptr==(f)->readlim && !Igetmore(f)) s else (c)= *(f)->ptr++
2419Sjkh#		define cachegeteof(c,s) if (ptr==rRILE->readlim && !Igetmore(rRILE)) s else (c)= *ptr++
2429Sjkh#	endif
2439Sjkh#	define uncache(f) ((f)->ptr = ptr)
2449Sjkh#	define cache(f) (ptr = (f)->ptr)
2459Sjkh#	define Iget(f,c) Igeteof(f,c,Ieof();)
2469Sjkh#	define cacheget(c) cachegeteof(c,Ieof();)
2479Sjkh#	define Itell(f) ((f)->ptr)
2489Sjkh#	define Iseek(f,p) ((f)->ptr = (p))
2499Sjkh#	define Irewind(f) Iseek(f, (f)->base)
2509Sjkh#	define cachetell() ptr
2519Sjkh#else
2529Sjkh#	define RILE FILE
2539Sjkh#	define declarecache register FILE *ptr
2549Sjkh#	define setupcache(f) (ptr = (f))
2559Sjkh#	define uncache(f)
2569Sjkh#	define cache(f)
2579Sjkh#	define Igeteof(f,c,s) if(((c)=getc(f))<0){testIerror(f);if(feof(f))s}else
2589Sjkh#	define cachegeteof(c,s) Igeteof(ptr,c,s)
2599Sjkh#	define Iget(f,c) if (((c)=getc(f))<0) testIeof(f); else
2609Sjkh#	define cacheget(c) Iget(ptr,c)
2619Sjkh#	define Ifileno(f) fileno(f)
2629Sjkh#endif
2639Sjkh
2649Sjkh/* Print a char, but abort on write error.  */
2659Sjkh#define aputc(c,o) if (putc(c,o)<0) testOerror(o); else
2669Sjkh
2679Sjkh/* Get a character from an RCS file, perhaps copying to a new RCS file.  */
2689Sjkh#define GETCeof(o,c,s) { cachegeteof(c,s); if (o) aputc(c,o); }
2699Sjkh#define GETC(o,c) { cacheget(c); if (o) aputc(c,o); }
2709Sjkh
2719Sjkh
2729Sjkh#define WORKMODE(RCSmode, writable) ((RCSmode)&~(S_IWUSR|S_IWGRP|S_IWOTH) | ((writable)?S_IWUSR:0))
2739Sjkh/* computes mode of working file: same as RCSmode, but write permission     */
2749Sjkh/* determined by writable */
2759Sjkh
2769Sjkh
2779Sjkh/* character classes and token codes */
2789Sjkhenum tokens {
2799Sjkh/* classes */	DELIM,	DIGIT,	IDCHAR,	NEWLN,	LETTER,	Letter,
2809Sjkh		PERIOD,	SBEGIN,	SPACE,	UNKN,
2819Sjkh/* tokens */	COLON,	ID,	NUM,	SEMI,	STRING
2829Sjkh};
2839Sjkh
2849Sjkh#define SDELIM  '@'     /* the actual character is needed for string handling*/
2859Sjkh/* SDELIM must be consistent with ctab[], so that ctab[SDELIM]==SBEGIN.
2869Sjkh * there should be no overlap among SDELIM, KDELIM, and VDELIM
2879Sjkh */
2889Sjkh
2899Sjkh#define isdigit(c) ((unsigned)((c)-'0') <= 9) /* faster than ctab[c]==DIGIT */
2909Sjkh
2919Sjkh
2929Sjkh
2939Sjkh
2949Sjkh
2959Sjkh/***************************************
2969Sjkh * Data structures for the symbol table
2979Sjkh ***************************************/
2989Sjkh
2999Sjkh/* Buffer of arbitrary data */
3009Sjkhstruct buf {
3019Sjkh	char *string;
3029Sjkh	size_t size;
3039Sjkh};
3049Sjkhstruct cbuf {
3059Sjkh	char const *string;
3069Sjkh	size_t size;
3079Sjkh};
3089Sjkh
3099Sjkh/* Hash table entry */
3109Sjkhstruct hshentry {
3119Sjkh	char const	  * num;      /* pointer to revision number (ASCIZ) */
3129Sjkh	char const	  * date;     /* pointer to date of checkin	    */
3139Sjkh	char const	  * author;   /* login of person checking in	    */
3149Sjkh	char const	  * lockedby; /* who locks the revision		    */
3159Sjkh	char const	  * state;    /* state of revision (Exp by default) */
3169Sjkh	struct cbuf	    log;      /* log message requested at checkin   */
3179Sjkh        struct branchhead * branches; /* list of first revisions on branches*/
3189Sjkh	struct cbuf	    ig;	      /* ignored phrases of revision	    */
3199Sjkh        struct hshentry   * next;     /* next revision on same branch       */
3209Sjkh	struct hshentry   * nexthsh;  /* next revision with same hash value */
3219Sjkh	unsigned long	    insertlns;/* lines inserted (computed by rlog)  */
3229Sjkh	unsigned long	    deletelns;/* lines deleted  (computed by rlog)  */
3239Sjkh	char		    selector; /* true if selected, false if deleted */
3249Sjkh};
3259Sjkh
3269Sjkh/* list of hash entries */
3279Sjkhstruct hshentries {
3289Sjkh	struct hshentries *rest;
3299Sjkh	struct hshentry *first;
3309Sjkh};
3319Sjkh
3329Sjkh/* list element for branch lists */
3339Sjkhstruct branchhead {
3349Sjkh        struct hshentry   * hsh;
3359Sjkh        struct branchhead * nextbranch;
3369Sjkh};
3379Sjkh
3389Sjkh/* accesslist element */
3399Sjkhstruct access {
3409Sjkh	char const	  * login;
3419Sjkh        struct access     * nextaccess;
3429Sjkh};
3439Sjkh
3449Sjkh/* list element for locks  */
3459Sjkhstruct lock {
3469Sjkh	char const	  * login;
3479Sjkh        struct hshentry   * delta;
3489Sjkh        struct lock       * nextlock;
3499Sjkh};
3509Sjkh
3519Sjkh/* list element for symbolic names */
3529Sjkhstruct assoc {
3539Sjkh	char const	  * symbol;
3549Sjkh	char const	  * num;
3559Sjkh        struct assoc      * nextassoc;
3569Sjkh};
3579Sjkh
3589Sjkh
3599Sjkh#define mainArgs (argc,argv) int argc; char **argv;
3609Sjkh
3619Sjkh#if lint
3629Sjkh#	define libId(name,rcsid)
3639Sjkh#	define mainProg(name,cmd,rcsid) int name mainArgs
3649Sjkh#else
3659Sjkh#	define libId(name,rcsid) char const name[] = rcsid;
3669Sjkh#	define mainProg(name,cmd,rcsid) char const copyright[] = "Copyright 1982,1988,1989 by Walter F. Tichy\nPurdue CS\nCopyright 1990,1991 by Paul Eggert", rcsbaseId[] = RCSBASE, cmdid[] = cmd; libId(name,rcsid) int main mainArgs
3679Sjkh#endif
3689Sjkh
3699Sjkh/*
3709Sjkh * Markers for keyword expansion (used in co and ident)
3719Sjkh *	Every byte must have class LETTER or Letter.
3729Sjkh */
3739Sjkh#define AUTHOR          "Author"
3749Sjkh#define DATE            "Date"
3759Sjkh#define HEADER          "Header"
3769Sjkh#define IDH             "Id"
3779Sjkh#define LOCKER          "Locker"
3789Sjkh#define LOG             "Log"
3799Sjkh#define RCSFILE         "RCSfile"
3809Sjkh#define REVISION        "Revision"
3819Sjkh#define SOURCE          "Source"
3829Sjkh#define STATE           "State"
3839Sjkh#define keylength 8 /* max length of any of the above keywords */
3849Sjkh
3859Sjkhenum markers { Nomatch, Author, Date, Header, Id,
3869Sjkh	       Locker, Log, RCSfile, Revision, Source, State };
3879Sjkh	/* This must be in the same order as rcskeys.c's Keyword[] array. */
3889Sjkh
3899Sjkh#define DELNUMFORM      "\n\n%s\n%s\n"
3909Sjkh/* used by putdtext and scanlogtext */
3919Sjkh
3929Sjkh#define EMPTYLOG "*** empty log message ***" /* used by ci and rlog */
3939Sjkh
3949Sjkh/* main program */
3959Sjkhextern char const cmdid[];
3969Sjkhexiting void exiterr P((void));
3979Sjkh
3989Sjkh/* maketime */
3999Sjkhint setfiledate P((char const*,char const[datesize]));
4009Sjkhvoid str2date P((char const*,char[datesize]));
4019Sjkhvoid time2date P((time_t,char[datesize]));
4029Sjkh
4039Sjkh/* merge */
4049Sjkhint merge P((int,char const*const[2],char const*const[3]));
4059Sjkh
4069Sjkh/* partime */
4079Sjkhint partime P((char const*,struct tm*,int*));
4089Sjkh
4099Sjkh/* rcsedit */
4109Sjkh#define ciklogsize 23 /* sizeof("checked in with -k by ") */
4119Sjkhextern FILE *fcopy;
4129Sjkhextern char const *resultfile;
4139Sjkhextern char const ciklog[ciklogsize];
4149Sjkhextern int locker_expansion;
4159Sjkhextern struct buf dirtfname[];
4169Sjkh#define newRCSfilename (dirtfname[0].string)
4179SjkhRILE *rcswriteopen P((struct buf*,struct stat*,int));
4189Sjkhchar const *makedirtemp P((char const*,int));
4199Sjkhchar const *getcaller P((void));
4209Sjkhint addlock P((struct hshentry*));
4219Sjkhint addsymbol P((char const*,char const*,int));
4229Sjkhint checkaccesslist P((void));
4239Sjkhint chnamemod P((FILE**,char const*,char const*,mode_t));
4249Sjkhint donerewrite P((int));
4259Sjkhint dorewrite P((int,int));
4269Sjkhint expandline P((RILE*,FILE*,struct hshentry const*,int,FILE*));
4279Sjkhint findlock P((int,struct hshentry**));
4289Sjkhvoid aflush P((FILE*));
4299Sjkhvoid copystring P((void));
4309Sjkhvoid dirtempunlink P((void));
4319Sjkhvoid enterstring P((void));
4329Sjkhvoid finishedit P((struct hshentry const*,FILE*,int));
4339Sjkhvoid keepdirtemp P((char const*));
4349Sjkhvoid openfcopy P((FILE*));
4359Sjkhvoid snapshotedit P((FILE*));
4369Sjkhvoid xpandstring P((struct hshentry const*));
4379Sjkh#if has_NFS || bad_unlink
4389Sjkh	int un_link P((char const*));
4399Sjkh#else
4409Sjkh#	define un_link(s) unlink(s)
4419Sjkh#endif
4429Sjkh#if large_memory
4439Sjkh	void edit_string P((void));
4449Sjkh#	define editstring(delta) edit_string()
4459Sjkh#else
4469Sjkh	void editstring P((struct hshentry const*));
4479Sjkh#endif
4489Sjkh
4499Sjkh/* rcsfcmp */
4509Sjkhint rcsfcmp P((RILE*,struct stat const*,char const*,struct hshentry const*));
4519Sjkh
4529Sjkh/* rcsfnms */
4539Sjkh#define bufautobegin(b) ((void) ((b)->string = 0, (b)->size = 0))
4549Sjkhextern FILE *workstdout;
4559Sjkhextern char *workfilename;
4569Sjkhextern char const *RCSfilename;
4579Sjkhextern char const *suffixes;
4589Sjkhextern struct stat RCSstat;
4599SjkhRILE *rcsreadopen P((struct buf*,struct stat*,int));
4609Sjkhchar *bufenlarge P((struct buf*,char const**));
4619Sjkhchar const *basename P((char const*));
4629Sjkhchar const *getfullRCSname P((void));
4639Sjkhchar const *maketemp P((int));
4649Sjkhchar const *rcssuffix P((char const*));
4659Sjkhint pairfilenames P((int,char**,RILE*(*)P((struct buf*,struct stat*,int)),int,int));
4669Sjkhsize_t dirlen P((char const*));
4679Sjkhstruct cbuf bufremember P((struct buf*,size_t));
4689Sjkhvoid bufalloc P((struct buf*,size_t));
4699Sjkhvoid bufautoend P((struct buf*));
4709Sjkhvoid bufrealloc P((struct buf*,size_t));
4719Sjkhvoid bufscat P((struct buf*,char const*));
4729Sjkhvoid bufscpy P((struct buf*,char const*));
4739Sjkhvoid tempunlink P((void));
4749Sjkh
4759Sjkh/* rcsgen */
4769Sjkhextern int interactiveflag;
4779Sjkhextern struct buf curlogbuf;
4789Sjkhchar const *buildrevision P((struct hshentries const*,struct hshentry*,FILE*,int));
4799Sjkhint getcstdin P((void));
4809Sjkhint ttystdin P((void));
4819Sjkhint yesorno P((int,char const*,...));
4829Sjkhstruct cbuf cleanlogmsg P((char*,size_t));
4839Sjkhstruct cbuf getsstdin P((char const*,char const*,char const*,struct buf*));
4849Sjkhvoid putdesc P((int,char*));
4859Sjkh
4869Sjkh/* rcskeep */
4879Sjkhextern int prevkeys;
4889Sjkhextern struct buf prevauthor, prevdate, prevrev, prevstate;
4899Sjkhint getoldkeys P((RILE*));
4909Sjkh
4919Sjkh/* rcskeys */
4929Sjkhextern char const *const Keyword[];
4939Sjkhenum markers trymatch P((char const*));
4949Sjkh
4959Sjkh/* rcslex */
4969Sjkhextern FILE *foutptr;
4979Sjkhextern FILE *frewrite;
4989Sjkhextern RILE *finptr;
4999Sjkhextern char const *NextString;
5009Sjkhextern enum tokens nexttok;
5019Sjkhextern int hshenter;
5029Sjkhextern int nerror;
5039Sjkhextern int nextc;
5049Sjkhextern int quietflag;
5059Sjkhextern unsigned long rcsline;
5069Sjkhchar const *getid P((void));
5079Sjkhexiting void efaterror P((char const*));
5089Sjkhexiting void enfaterror P((int,char const*));
5099Sjkhexiting void faterror P((char const*,...));
5109Sjkhexiting void fatserror P((char const*,...));
5119Sjkhexiting void Ieof P((void));
5129Sjkhexiting void Ierror P((void));
5139Sjkhexiting void Oerror P((void));
5149Sjkhchar *checkid P((char*,int));
5159Sjkhint eoflex P((void));
5169Sjkhint getkeyopt P((char const*));
5179Sjkhint getlex P((enum tokens));
5189Sjkhstruct cbuf getphrases P((char const*));
5199Sjkhstruct cbuf savestring P((struct buf*));
5209Sjkhstruct hshentry *getnum P((void));
5219Sjkhvoid Ifclose P((RILE*));
5229Sjkhvoid Izclose P((RILE**));
5239Sjkhvoid Lexinit P((void));
5249Sjkhvoid Ofclose P((FILE*));
5259Sjkhvoid Ozclose P((FILE**));
5269Sjkhvoid afputc P((int,FILE*));
5279Sjkhvoid aprintf P((FILE*,char const*,...));
5289Sjkhvoid aputs P((char const*,FILE*));
5299Sjkhvoid checksid P((char*));
5309Sjkhvoid diagnose P((char const*,...));
5319Sjkhvoid eerror P((char const*));
5329Sjkhvoid eflush P((void));
5339Sjkhvoid enerror P((int,char const*));
5349Sjkhvoid error P((char const*,...));
5359Sjkhvoid fvfprintf P((FILE*,char const*,va_list));
5369Sjkhvoid getkey P((char const*));
5379Sjkhvoid getkeystring P((char const*));
5389Sjkhvoid nextlex P((void));
5399Sjkhvoid oflush P((void));
5409Sjkhvoid printstring P((void));
5419Sjkhvoid readstring P((void));
5429Sjkhvoid redefined P((int));
5439Sjkhvoid testIerror P((FILE*));
5449Sjkhvoid testOerror P((FILE*));
5459Sjkhvoid warn P((char const*,...));
5469Sjkhvoid warnignore P((void));
5479Sjkh#if has_madvise && has_mmap && large_memory
5489Sjkh	void advise_access P((RILE*,int));
5499Sjkh#	define if_advise_access(p,f,advice) if (p) advise_access(f,advice)
5509Sjkh#else
5519Sjkh#	define advise_access(f,advice)
5529Sjkh#	define if_advise_access(p,f,advice)
5539Sjkh#endif
5549Sjkh#if has_mmap && large_memory
5559Sjkh	RILE *I_open P((char const*,struct stat*));
5569Sjkh#	define Iopen(f,m,s) I_open(f,s)
5579Sjkh#else
5589Sjkh	RILE *Iopen P((char const*,char const*,struct stat*));
5599Sjkh#endif
5609Sjkh#if !large_memory
5619Sjkh	void testIeof P((FILE*));
5629Sjkh	void Irewind P((RILE*));
5639Sjkh#endif
5649Sjkh
5659Sjkh/* rcsmap */
5669Sjkhextern const enum tokens ctab[];
5679Sjkh
5689Sjkh/* rcsrev */
5699Sjkhchar *partialno P((struct buf*,char const*,unsigned));
5709Sjkhchar const *tiprev P((void));
5719Sjkhint cmpnum P((char const*,char const*));
5729Sjkhint cmpnumfld P((char const*,char const*,unsigned));
5739Sjkhint compartial P((char const*,char const*,unsigned));
5749Sjkhint expandsym P((char const*,struct buf*));
5759Sjkhint fexpandsym P((char const*,struct buf*,RILE*));
5769Sjkhstruct hshentry *genrevs P((char const*,char const*,char const*,char const*,struct hshentries**));
5779Sjkhunsigned countnumflds P((char const*));
5789Sjkhvoid getbranchno P((char const*,struct buf*));
5799Sjkh
5809Sjkh/* rcssyn */
5819Sjkh/* These expand modes must agree with Expand_names[] in rcssyn.c.  */
5829Sjkh#define KEYVAL_EXPAND 0 /* -kkv `$Keyword: value $' */
5839Sjkh#define KEYVALLOCK_EXPAND 1 /* -kkvl `$Keyword: value locker $' */
5849Sjkh#define KEY_EXPAND 2 /* -kk `$Keyword$' */
5859Sjkh#define VAL_EXPAND 3 /* -kv `value' */
5869Sjkh#define OLD_EXPAND 4 /* -ko use old string, omitting expansion */
5879Sjkhstruct diffcmd {
5889Sjkh	unsigned long
5899Sjkh		line1, /* number of first line */
5909Sjkh		nlines, /* number of lines affected */
5919Sjkh		adprev, /* previous 'a' line1+1 or 'd' line1 */
5929Sjkh		dafter; /* sum of previous 'd' line1 and previous 'd' nlines */
5939Sjkh};
5949Sjkhextern char const      * Dbranch;
5959Sjkhextern struct access   * AccessList;
5969Sjkhextern struct assoc    * Symbols;
5979Sjkhextern struct cbuf Comment;
5989Sjkhextern struct lock     * Locks;
5999Sjkhextern struct hshentry * Head;
6009Sjkhextern int		 Expand;
6019Sjkhextern int               StrictLocks;
6029Sjkhextern unsigned TotalDeltas;
6039Sjkhextern char const *const expand_names[];
6049Sjkhextern char const Kdesc[];
6059Sjkhextern char const Klog[];
6069Sjkhextern char const Ktext[];
6079Sjkhint getdiffcmd P((RILE*,int,FILE*,struct diffcmd*));
6089Sjkhint putdftext P((char const*,struct cbuf,RILE*,FILE*,int));
6099Sjkhint putdtext P((char const*,struct cbuf,char const*,FILE*,int));
6109Sjkhint str2expmode P((char const*));
6119Sjkhvoid getadmin P((void));
6129Sjkhvoid getdesc P((int));
6139Sjkhvoid gettree P((void));
6149Sjkhvoid ignorephrase P((void));
6159Sjkhvoid initdiffcmd P((struct diffcmd*));
6169Sjkhvoid putadmin P((FILE*));
6179Sjkhvoid putstring P((FILE*,int,struct cbuf,int));
6189Sjkhvoid puttree P((struct hshentry const*,FILE*));
6199Sjkh
6209Sjkh/* rcsutil */
6219Sjkhextern int RCSversion;
6229Sjkhchar *cgetenv P((char const*));
6239Sjkhchar *fstr_save P((char const*));
6249Sjkhchar *str_save P((char const*));
6259Sjkhchar const *date2str P((char const[datesize],char[datesize]));
6269Sjkhchar const *getusername P((int));
6279Sjkhint getRCSINIT P((int,char**,char***));
6289Sjkhint run P((char const*,char const*,...));
6299Sjkhint runv P((char const**));
6309Sjkhmalloc_type fremember P((malloc_type));
6319Sjkhmalloc_type ftestalloc P((size_t));
6329Sjkhmalloc_type testalloc P((size_t));
6339Sjkhmalloc_type testrealloc P((malloc_type,size_t));
6349Sjkh#define ftalloc(T) ftnalloc(T,1)
6359Sjkh#define talloc(T) tnalloc(T,1)
6369Sjkh#if lint
6379Sjkh	extern malloc_type lintalloc;
6389Sjkh#	define ftnalloc(T,n) (lintalloc = ftestalloc(sizeof(T)*(n)), (T*)0)
6399Sjkh#	define tnalloc(T,n) (lintalloc = testalloc(sizeof(T)*(n)), (T*)0)
6409Sjkh#	define trealloc(T,p,n) (lintalloc = testrealloc((malloc_type)0, sizeof(T)*(n)), p)
6419Sjkh#	define tfree(p)
6429Sjkh#else
6439Sjkh#	define ftnalloc(T,n) ((T*) ftestalloc(sizeof(T)*(n)))
6449Sjkh#	define tnalloc(T,n) ((T*) testalloc(sizeof(T)*(n)))
6459Sjkh#	define trealloc(T,p,n) ((T*) testrealloc((malloc_type)(p), sizeof(T)*(n)))
6469Sjkh#	define tfree(p) free((malloc_type)(p))
6479Sjkh#endif
6489Sjkhvoid awrite P((char const*,size_t,FILE*));
6499Sjkhvoid fastcopy P((RILE*,FILE*));
6509Sjkhvoid ffree P((void));
6519Sjkhvoid ffree1 P((char const*));
6529Sjkhvoid setRCSversion P((char const*));
6539Sjkh#if has_signal
6549Sjkh	void catchints P((void));
6559Sjkh	void ignoreints P((void));
6569Sjkh	void restoreints P((void));
6579Sjkh#else
6589Sjkh#	define catchints()
6599Sjkh#	define ignoreints()
6609Sjkh#	define restoreints()
6619Sjkh#endif
6629Sjkh#if has_getuid
6639Sjkh	uid_t ruid P((void));
6649Sjkh#	define myself(u) ((u) == ruid())
6659Sjkh#else
6669Sjkh#	define myself(u) true
6679Sjkh#endif
6689Sjkh#if has_setuid
6699Sjkh	uid_t euid P((void));
6709Sjkh	void nosetid P((void));
6719Sjkh	void seteid P((void));
6729Sjkh	void setrid P((void));
6739Sjkh#else
6749Sjkh#	define nosetid()
6759Sjkh#	define seteid()
6769Sjkh#	define setrid()
6779Sjkh#endif
678