⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rcsfnms.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *                     RCS file name handling *//**************************************************************************** *                     creation and deletion of /tmp temporaries *                     pairing of RCS file names and working file names. *                     Testprogram: define PAIRTEST **************************************************************************** *//* Copyright (C) 1982, 1988, 1989 Walter Tichy   Copyright 1990, 1991 by Paul Eggert   Distributed under license by the Free Software Foundation, Inc.This file is part of RCS.RCS is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.RCS is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with RCS; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.Report problems and direct all questions to:    rcs-bugs@cs.purdue.edu*//* $Log: rcsfnms.c,v $ * Revision 5.8  1991/09/24  00:28:40  eggert * Don't export bindex(). * * Revision 5.7  1991/08/19  03:13:55  eggert * Fix messages when rcswriteopen fails. * Look in $TMP and $TEMP if $TMPDIR isn't set.  Tune. * * Revision 5.6  1991/04/21  11:58:23  eggert * Fix errno bugs.  Add -x, RCSINIT, MS-DOS support. * * Revision 5.5  1991/02/26  17:48:38  eggert * Fix setuid bug.  Support new link behavior. * Define more portable getcwd(). * * Revision 5.4  1990/11/01  05:03:43  eggert * Permit arbitrary data in comment leaders. * * Revision 5.3  1990/09/14  22:56:16  hammer * added more filename extensions and their comment leaders * * Revision 5.2  1990/09/04  08:02:23  eggert * Fix typo when !RCSSEP. * * Revision 5.1  1990/08/29  07:13:59  eggert * Work around buggy compilers with defective argument promotion. * * Revision 5.0  1990/08/22  08:12:50  eggert * Ignore signals when manipulating the semaphore file. * Modernize list of file name extensions. * Permit paths of arbitrary length.  Beware file names beginning with "-". * Remove compile-time limits; use malloc instead. * Permit dates past 1999/12/31.  Make lock and temp files faster and safer. * Ansify and Posixate. * Don't use access().  Fix test for non-regular files.  Tune. * * Revision 4.8  89/05/01  15:09:41  narten * changed getwd to not stat empty directories. *  * Revision 4.7  88/08/09  19:12:53  eggert * Fix troff macro comment leader bug; add Prolog; allow cc -R; remove lint. *  * Revision 4.6  87/12/18  11:40:23  narten * additional file types added from 4.3 BSD version, and SPARC assembler * comment character added. Also, more lint cleanups. (Guy Harris) *  * Revision 4.5  87/10/18  10:34:16  narten * Updating version numbers. Changes relative to 1.1 actually relative * to verion 4.3 *  * Revision 1.3  87/03/27  14:22:21  jenkins * Port to suns *  * Revision 1.2  85/06/26  07:34:28  svb * Comment leader '% ' for '*.tex' files added. *  * Revision 4.3  83/12/15  12:26:48  wft * Added check for KDELIM in file names to pairfilenames(). *  * Revision 4.2  83/12/02  22:47:45  wft * Added csh, red, and sl file name suffixes. *  * Revision 4.1  83/05/11  16:23:39  wft * Added initialization of Dbranch to InitAdmin(). Canged pairfilenames(): * 1. added copying of path from workfile to RCS file, if RCS file is omitted; * 2. added getting the file status of RCS and working files; * 3. added ignoring of directories. *  * Revision 3.7  83/05/11  15:01:58  wft * Added comtable[] which pairs file name suffixes with comment leaders; * updated InitAdmin() accordingly. *  * Revision 3.6  83/04/05  14:47:36  wft * fixed Suffix in InitAdmin(). *  * Revision 3.5  83/01/17  18:01:04  wft * Added getwd() and rename(); these can be removed by defining * V4_2BSD, since they are not needed in 4.2 bsd. * Changed sys/param.h to sys/types.h. * * Revision 3.4  82/12/08  21:55:20  wft * removed unused variable. * * Revision 3.3  82/11/28  20:31:37  wft * Changed mktempfile() to store the generated file names. * Changed getfullRCSname() to store the file and pathname, and to * delete leading "../" and "./". * * Revision 3.2  82/11/12  14:29:40  wft * changed pairfilenames() to handle file.sfx,v; also deleted checkpathnosfx(), * checksuffix(), checkfullpath(). Semaphore name generation updated. * mktempfile() now checks for nil path; freefilename initialized properly. * Added Suffix .h to InitAdmin. Added testprogram PAIRTEST. * Moved rmsema, trysema, trydiraccess, getfullRCSname from rcsutil.c to here. * * Revision 3.1  82/10/18  14:51:28  wft * InitAdmin() now initializes StrictLocks=STRICT_LOCKING (def. in rcsbase.h). * renamed checkpath() to checkfullpath(). */#include "rcsbase.h"libId(fnmsId, "$Id: rcsfnms.c,v 5.8 1991/09/24 00:28:40 eggert Exp $")char const *RCSfilename;char *workfilename;FILE *workstdout;struct stat RCSstat;char const *suffixes;static char const rcsdir[] = "RCS";#define rcsdirlen (sizeof(rcsdir)-1)static struct buf RCSbuf, RCSb;static int RCSerrno;/* Temp file names to be unlinked when done, if they are not nil.  */#define TEMPNAMES 5 /* must be at least DIRTEMPNAMES (see rcsedit.c) */static char *volatile tfnames[TEMPNAMES];struct compair {	char const *suffix, *comlead;};static struct compair const comtable[] = {/* comtable pairs each filename suffix with a comment leader. The comment   *//* leader is placed before each line generated by the $Log keyword. This    *//* table is used to guess the proper comment leader from the working file's *//* suffix during initial ci (see InitAdmin()). Comment leaders are needed   *//* for languages without multiline comments; for others they are optional.  */	"a",   "-- ",   /* Ada         */	"ada", "-- ",	"asm", ";; ",	/* assembler (MS-DOS) */	"bat", ":: ",	/* batch (MS-DOS) */        "c",   " * ",   /* C           */	"c++", "// ",	/* C++ in all its infinite guises */	"cc",  "// ",	"cpp", "// ",	"cxx", "// ",	"cl",  ";;; ",  /* Common Lisp */	"cmd", ":: ",	/* command (OS/2) */	"cmf", "c ",	/* CM Fortran  */	"cs",  " * ",	/* C*          */	"el",  "; ",    /* Emacs Lisp  */	"f",   "c ",    /* Fortran     */	"for", "c ",        "h",   " * ",   /* C-header    */	"hpp", "// ",	/* C++ header  */	"hxx", "// ",        "l",   " * ",   /* lex      NOTE: conflict between lex and franzlisp */	"lisp",";;; ",	/* Lucid Lisp  */	"lsp", ";; ",	/* Microsoft Lisp */	"mac", ";; ",	/* macro (DEC-10, MS-DOS, PDP-11, VMS, etc) */	"me",  ".\\\" ",/* me-macros   t/nroff*/	"ml",  "; ",    /* mocklisp    */	"mm",  ".\\\" ",/* mm-macros   t/nroff*/	"ms",  ".\\\" ",/* ms-macros   t/nroff*/	"p",   " * ",   /* Pascal      */	"pas", " * ",	"pl",  "% ",	/* Prolog      */	"tex", "% ",	/* TeX	       */        "y",   " * ",   /* yacc        */	nil,   "# "     /* default for unknown suffix; must always be last */};#if has_mktemp	static char const *tmp()/* Yield the name of the tmp directory.  */{	static char const *s;	if (!s		&&  !(s = cgetenv("TMPDIR"))	/* Unix tradition */		&&  !(s = cgetenv("TMP"))	/* DOS tradition */		&&  !(s = cgetenv("TEMP"))	/* another DOS tradition */	)		s = TMPDIR;	return s;}#endif	char const *maketemp(n)	int n;/* Create a unique filename using n and the process id and store it * into the nth slot in tfnames. * Because of storage in tfnames, tempunlink() can unlink the file later. * Returns a pointer to the filename created. */{	char *p;	char const *t = tfnames[n];	if (t)		return t;	catchints();	{#	if has_mktemp	    char const *tp = tmp();	    p = testalloc(strlen(tp) + 10);	    VOID sprintf(p, "%s%cT%cXXXXXX", tp, SLASH, '0'+n);	    if (!mktemp(p) || !*p)		faterror("can't make temporary file name `%s%cT%cXXXXXX'",			tp, SLASH, '0'+n		);#	else	    static char tfnamebuf[TEMPNAMES][L_tmpnam];	    p = tfnamebuf[n];	    if (!tmpnam(p) || !*p)#		ifdef P_tmpdir		    faterror("can't make temporary file name `%s...'",P_tmpdir);#		else		    faterror("can't make temporary file name");#		endif#	endif	}	tfnames[n] = p;	return p;}	voidtempunlink()/* Clean up maketemp() files.  May be invoked by signal handler. */{	register int i;	register char *p;	for (i = TEMPNAMES;  0 <= --i;  )	    if ((p = tfnames[i])) {		VOID unlink(p);		/*		 * We would tfree(p) here,		 * but this might dump core if we're handing a signal.		 * We're about to exit anyway, so we won't bother.		 */		tfnames[i] = 0;	    }}	static char const *bindex(sp,ch)	register char const *sp;	int ch;/* Function: Finds the last occurrence of character c in string sp * and returns a pointer to the character just beyond it. If the * character doesn't occur in the string, sp is returned. */{	register char const c=ch, *r;        r = sp;        while (*sp) {                if (*sp++ == c) r=sp;        }        return r;}	static intsuffix_matches(suffix, pattern)	register char const *suffix, *pattern;{	register int c;	if (!pattern)		return true;	for (;;)		switch (*suffix++ - (c = *pattern++)) {		    case 0:			if (!c)				return true;			break;		    case 'A'-'a':			if (ctab[c] == Letter)				break;			/* fall into */		    default:			return false;		}}	static voidInitAdmin()/* function: initializes an admin node */{	register char const *Suffix;        register int i;	Head=nil; Dbranch=nil; AccessList=nil; Symbols=nil; Locks=nil;        StrictLocks=STRICT_LOCKING;        /* guess the comment leader from the suffix*/        Suffix=bindex(workfilename, '.');        if (Suffix==workfilename) Suffix= ""; /* empty suffix; will get default*/	for (i=0; !suffix_matches(Suffix,comtable[i].suffix); i++)		;	Comment.string = comtable[i].comlead;	Comment.size = strlen(comtable[i].comlead);	Lexinit(); /* note: if !finptr, reads nothing; only initializes */}#if defined(_POSIX_NO_TRUNC)#	define LONG_NAMES_MAY_BE_SILENTLY_TRUNCATED 0#else#	define LONG_NAMES_MAY_BE_SILENTLY_TRUNCATED 1#endif#if LONG_NAMES_MAY_BE_SILENTLY_TRUNCATED#ifdef NAME_MAX#	define filenametoolong(path) (NAME_MAX < strlen(basename(path)))#else	static intfilenametoolong(path)	char *path;/* Yield true if the last file name in PATH is too long. */{	static unsigned long dot_namemax;	register size_t namelen;	register char *base;	register unsigned long namemax;	base = path + dirlen(path);	namelen = strlen(base);	if (namelen <= _POSIX_NAME_MAX) /* fast check for shorties */		return false;	if (base != path) {		*--base = 0;		namemax = pathconf(path, _PC_NAME_MAX);		*base = SLASH;	} else {		/* Cache the results for the working directory, for speed. */		if (!dot_namemax)			dot_namemax = pathconf(".", _PC_NAME_MAX);		namemax = dot_namemax;	}	/* If pathconf() yielded -1, namemax is now ULONG_MAX.  */	return namemax<namelen;}#endif#endif	voidbufalloc(b, size)	register struct buf *b;	size_t size;/* Ensure *B is a name buffer of at least SIZE bytes. * *B's old contents can be freed; *B's new contents are undefined. */{	if (b->size < size) {		if (b->size)			tfree(b->string);		else			b->size = sizeof(malloc_type);		while (b->size < size)			b->size <<= 1;		b->string = tnalloc(char, b->size);	}}	voidbufrealloc(b, size)	register struct buf *b;	size_t size;/* like bufalloc, except *B's old contents, if any, are preserved */{	if (b->size < size) {		if (!b->size)			bufalloc(b, size);		else {			while ((b->size <<= 1)  <  size)				;			b->string = trealloc(char, b->string, b->size);		}	}}	voidbufautoend(b)	struct buf *b;/* Free an auto buffer at block exit. */{	if (b->size)		tfree(b->string);}	struct cbufbufremember(b, s)	struct buf *b;	size_t s;/* * Free the buffer B with used size S. * Yield a cbuf with identical contents. * The cbuf will be reclaimed when this input file is finished. */{	struct cbuf cb;	if ((cb.size = s))		cb.string = fremember(trealloc(char, b->string, s));	else {		bufautoend(b); /* not really auto */		cb.string = "";	}	return cb;}	char *bufenlarge(b, alim)	register struct buf *b;	char const **alim;/* Make *B larger.  Set *ALIM to its new limit, and yield the relocated value * of its old limit. */{	size_t s = b->size;	bufrealloc(b, s + 1);	*alim = b->string + b->size;	return b->string + s;}	voidbufscat(b, s)	struct buf *b;	char const *s;/* Concatenate S to B's end. */{	size_t blen  =  b->string ? strlen(b->string) : 0;	bufrealloc(b, blen+strlen(s)+1);	VOID strcpy(b->string+blen, s);}	voidbufscpy(b, s)	struct buf *b;	char const *s;/* Copy S into B. */{	bufalloc(b, strlen(s)+1);	VOID strcpy(b->string, s);}	char const *basename(p)	char const *p;/* Yield the address of the base filename of the pathname P.  */{	register char const *b = p, *q = p;	for (;;)	    switch (*q++) {		case SLASHes: b = q; break;		case 0: return b;	    }}	size_tdirlen(p)	char const *p;/* Yield the length of P's directory, including its trailing SLASH.  */{	return basename(p) - p;}	static size_tsuffixlen(x)	char const *x;/* Yield the length of X, an RCS filename suffix.  */{	register char const *p;	p = x;	for (;;)	    switch (*p) {		case 0: case SLASHes:		    return p - x;		default:		    ++p;		    continue;	    }}	char const *rcssuffix(name)	char const *name;/* Yield the suffix of NAME if it is an RCS filename, 0 otherwise.  */{	char const *x, *p, *nz;	size_t dl, nl, xl;	nl = strlen(name);	nz = name + nl;	x = suffixes;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -