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

📄 routines.c

📁 Exuberant Ctags is a multilanguage reimplementation of the much-underused ctags(1) program and is i
💻 C
📖 第 1 页 / 共 2 页
字号:
				file.isExecutable = (boolean) ((status.st_mode &					(S_IXUSR | S_IXGRP | S_IXOTH)) != 0);				file.isSetuid = (boolean) ((status.st_mode & S_ISUID) != 0);				file.size = status.st_size;			}		}	}	return &file;}extern boolean doesFileExist (const char *const fileName){	fileStatus *status = eStat (fileName);	return status->exists;}extern boolean isRecursiveLink (const char* const dirName){	boolean result = FALSE;	fileStatus *status = eStat (dirName);	if (status->isSymbolicLink)	{		char* const path = absoluteFilename (dirName);		while (path [strlen (path) - 1] == PATH_SEPARATOR)			path [strlen (path) - 1] = '\0';		while (! result  &&  strlen (path) > (size_t) 1)		{			char *const separator = strrchr (path, PATH_SEPARATOR);			if (separator == NULL)				break;			else if (separator == path)  /* backed up to root directory */				*(separator + 1) = '\0';			else				*separator = '\0';			result = isSameFile (path, dirName);		}		eFree (path);	}	return result;}#ifndef HAVE_FGETPOSextern int fgetpos (FILE *stream, fpos_t *pos){	int result = 0;	*pos = ftell (stream);	if (*pos == -1L)		result = -1;	return result;}extern int fsetpos (FILE *stream, fpos_t const *pos){	return fseek (stream, *pos, SEEK_SET);}#endif/* *  Pathname manipulation (O/S dependent!!!) */static boolean isPathSeparator (const int c){	boolean result;#if defined (MSDOS_STYLE_PATH) || defined (VMS)	result = (boolean) (strchr (PathDelimiters, c) != NULL);#else	result = (boolean) (c == PATH_SEPARATOR);#endif	return result;}#if ! defined (HAVE_STAT_ST_INO)static void canonicalizePath (char *const path __unused__){#if defined (MSDOS_STYLE_PATH)	char *p;	for (p = path  ;  *p != '\0'  ;  ++p)		if (isPathSeparator (*p)  &&  *p != ':')			*p = PATH_SEPARATOR;#endif}#endifextern boolean isSameFile (const char *const name1, const char *const name2){	boolean result = FALSE;#if defined (HAVE_STAT_ST_INO)	struct stat stat1, stat2;	if (stat (name1, &stat1) == 0  &&  stat (name2, &stat2) == 0)		result = (boolean) (stat1.st_ino == stat2.st_ino);#else	{		char *const n1 = absoluteFilename (name1);		char *const n2 = absoluteFilename (name2);		canonicalizePath (n1);		canonicalizePath (n2);# if defined (CASE_INSENSITIVE_FILENAMES)		result = (boolean) (strcasecmp (n1, n2) == 0);#else		result = (boolean) (strcmp (n1, n2) == 0);#endif		free (n1);		free (n2);	}#endif	return result;}extern const char *baseFilename (const char *const filePath){#if defined (MSDOS_STYLE_PATH) || defined (VMS)	const char *tail = NULL;	unsigned int i;	/*  Find whichever of the path delimiters is last.	 */	for (i = 0  ;  i < strlen (PathDelimiters)  ;  ++i)	{		const char *sep = strrchr (filePath, PathDelimiters [i]);		if (sep > tail)			tail = sep;	}#else	const char *tail = strrchr (filePath, PATH_SEPARATOR);#endif	if (tail == NULL)		tail = filePath;	else		++tail;  /* step past last delimiter */#ifdef VAXC	{		/* remove version number from filename */		char *p = strrchr ((char *) tail, ';');		if (p != NULL)			*p = '\0';	}#endif	return tail;}extern const char *fileExtension (const char *const fileName){	const char *extension;	const char *pDelimiter = NULL;	const char *const base = baseFilename (fileName);#ifdef QDOS	pDelimiter = strrchr (base, '_');#endif	if (pDelimiter == NULL)	    pDelimiter = strrchr (base, '.');	if (pDelimiter == NULL)		extension = "";	else		extension = pDelimiter + 1;  /* skip to first char of extension */	return extension;}extern boolean isAbsolutePath (const char *const path){	boolean result = FALSE;#if defined (MSDOS_STYLE_PATH)	if (isPathSeparator (path [0]))		result = TRUE;	else if (isalpha (path [0])  &&  path [1] == ':')	{		if (isPathSeparator (path [2]))			result = TRUE;		else			/*  We don't support non-absolute file names with a drive			 *  letter, like `d:NAME' (it's too much hassle).			 */			error (FATAL,				"%s: relative file names with drive letters not supported",				path);	}#elif defined (VMS)	result = (boolean) (strchr (path, ':') != NULL);#else	result = isPathSeparator (path [0]);#endif	return result;}extern vString *combinePathAndFile (	const char *const path, const char *const file){	vString *const filePath = vStringNew ();#ifdef VMS	const char *const directoryId = strstr (file, ".DIR;1");	if (directoryId == NULL)	{		const char *const versionId = strchr (file, ';');		vStringCopyS (filePath, path);		if (versionId == NULL)			vStringCatS (filePath, file);		else			vStringNCatS (filePath, file, versionId - file);		vStringCopyToLower (filePath, filePath);	}	else	{		/*  File really is a directory; append it to the path.		 *  Gotcha: doesn't work with logical names.		 */		vStringNCopyS (filePath, path, strlen (path) - 1);		vStringPut (filePath, '.');		vStringNCatS (filePath, file, directoryId - file);		if (strchr (path, '[') != NULL)			vStringPut (filePath, ']');		else			vStringPut (filePath, '>');		vStringTerminate (filePath);	}#else	const int lastChar = path [strlen (path) - 1];	boolean terminated = isPathSeparator (lastChar);	vStringCopyS (filePath, path);	if (! terminated)	{		vStringPut (filePath, OUTPUT_PATH_SEPARATOR);		vStringTerminate (filePath);	}	vStringCatS (filePath, file);#endif	return filePath;}/* Return a newly-allocated string whose contents concatenate those of * s1, s2, s3. * Routine adapted from Gnu etags. */static char* concat (const char *s1, const char *s2, const char *s3){  int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);  char *result = xMalloc (len1 + len2 + len3 + 1, char);  strcpy (result, s1);  strcpy (result + len1, s2);  strcpy (result + len1 + len2, s3);  result [len1 + len2 + len3] = '\0';  return result;}/* Return a newly allocated string containing the absolute file name of FILE * given CWD (which should end with a slash). * Routine adapted from Gnu etags. */extern char* absoluteFilename (const char *file){	char *slashp, *cp;	char *res = NULL;	if (isAbsolutePath (file))	{#ifdef MSDOS_STYLE_PATH		if (file [1] == ':')			res = eStrdup (file);		else		{			char drive [3];			sprintf (drive, "%c:", currentdrive ());			res = concat (drive, file, "");		}#else		res = eStrdup (file);#endif	}	else		res = concat (CurrentDirectory, file, "");	/* Delete the "/dirname/.." and "/." substrings. */	slashp = strchr (res, PATH_SEPARATOR);	while (slashp != NULL  &&  slashp [0] != '\0')	{		if (slashp[1] == '.')		{			if (slashp [2] == '.' &&				(slashp [3] == PATH_SEPARATOR || slashp [3] == '\0'))			{				cp = slashp;				do					cp--;				while (cp >= res  &&  ! isAbsolutePath (cp));				if (cp < res)					cp = slashp;/* the absolute name begins with "/.." */#ifdef MSDOS_STYLE_PATH				/* Under MSDOS and NT we get `d:/NAME' as absolute file name,				 * so the luser could say `d:/../NAME'. We silently treat this				 * as `d:/NAME'.				 */				else if (cp [0] != PATH_SEPARATOR)					cp = slashp;#endif				strcpy (cp, slashp + 3);				slashp = cp;				continue;			}			else if (slashp [2] == PATH_SEPARATOR  ||  slashp [2] == '\0')			{				strcpy (slashp, slashp + 2);				continue;			}		}		slashp = strchr (slashp + 1, PATH_SEPARATOR);	}	if (res [0] == '\0')		return eStrdup ("/");	else	{#ifdef MSDOS_STYLE_PATH		/* Canonicalize drive letter case. */		if (res [1] == ':'  &&  islower (res [0]))			res [0] = toupper (res [0]);#endif		return res;	}}/* Return a newly allocated string containing the absolute file name of dir * where `file' resides given `CurrentDirectory'. * Routine adapted from Gnu etags. */extern char* absoluteDirname (char *file){	char *slashp, *res;	char save;	slashp = strrchr (file, PATH_SEPARATOR);	if (slashp == NULL)		res = eStrdup (CurrentDirectory);	else	{		save = slashp [1];		slashp [1] = '\0';		res = absoluteFilename (file);		slashp [1] = save;	}	return res;}/* Return a newly allocated string containing the file name of FILE relative * to the absolute directory DIR (which should end with a slash). * Routine adapted from Gnu etags. */extern char* relativeFilename (const char *file, const char *dir){	const char *fp, *dp;	char *absdir, *res;	int i;	/* Find the common root of file and dir (with a trailing slash). */	absdir = absoluteFilename (file);	fp = absdir;	dp = dir;	while (*fp++ == *dp++)		continue;	fp--;	dp--;  /* back to the first differing char */	do	{  /* look at the equal chars until path sep */		if (fp == absdir)			return absdir;  /* first char differs, give up */		fp--;		dp--;	} while (*fp != PATH_SEPARATOR);	/* Build a sequence of "../" strings for the resulting relative file name.	 */	i = 0;	while ((dp = strchr (dp + 1, PATH_SEPARATOR)) != NULL)		i += 1;	res = xMalloc (3 * i + strlen (fp + 1) + 1, char);	res [0] = '\0';	while (i-- > 0)		strcat (res, "../");	/* Add the file name relative to the common root of file and dir. */	strcat (res, fp + 1);	free (absdir);	return res;}extern FILE *tempFile (const char *const mode, char **const pName){	char *name;	FILE *fp;	int fd;#if defined(HAVE_MKSTEMP)	const char *const pattern = "tags.XXXXXX";	const char *tmpdir = NULL;	fileStatus *file = eStat (ExecutableProgram);	if (! file->isSetuid)		tmpdir = getenv ("TMPDIR");	if (tmpdir == NULL)		tmpdir = TMPDIR;	name = xMalloc (strlen (tmpdir) + 1 + strlen (pattern) + 1, char);	sprintf (name, "%s%c%s", tmpdir, OUTPUT_PATH_SEPARATOR, pattern);	fd = mkstemp (name);#elif defined(HAVE_TEMPNAM)	name = tempnam (TMPDIR, "tags");	if (name == NULL)		error (FATAL | PERROR, "cannot allocate temporary file name");	fd = open (name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);#else	name = xMalloc (L_tmpnam, char);	if (tmpnam (name) != name)		error (FATAL | PERROR, "cannot assign temporary file name");	fd = open (name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);#endif	if (fd == -1)		error (FATAL | PERROR, "cannot open temporary file");	fp = fdopen (fd, mode);	if (fp == NULL)		error (FATAL | PERROR, "cannot open temporary file");	DebugStatement (		debugPrintf (DEBUG_STATUS, "opened temporary file %s\n", name); )	Assert (*pName == NULL);	*pName = name;	return fp;}/* vi:set tabstop=4 shiftwidth=4: */

⌨️ 快捷键说明

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