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

📄 routines.c

📁 ultraEdit的Ctag标签工具的实现源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*   $Id: routines.c,v 1.21 2003/10/31 04:15:35 darren Exp $
*
*   Copyright (c) 2002-2003, Darren Hiebert
*
*   This source code is released for free distribution under the terms of the
*   GNU General Public License.
*
*   This module contains a lose assortment of shared functions.
*/

/*
*   INCLUDE FILES
*/
#include "general.h"	/* must always come first */

#ifdef HAVE_STDLIB_H
# include <stdlib.h>	/* to declare malloc (), realloc () */
#endif
#include <ctype.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <stdio.h>	/* to declare tempnam(), and SEEK_SET (hopefully) */

#ifdef HAVE_FCNTL_H
# include <fcntl.h>	/* to declar O_RDWR, O_CREAT, O_EXCL */
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>	/* to declare mkstemp () */
#endif

/*  To declare "struct stat" and stat ().
 */
#if defined (HAVE_SYS_TYPES_H)
# include <sys/types.h>
#else
# if defined (HAVE_TYPES_H)
#  include <types.h>
# endif
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#else
# ifdef HAVE_STAT_H
#  include <stat.h>
# endif
#endif

#ifdef HAVE_DOS_H
# include <dos.h>	/* to declare MAXPATH */
#endif
#ifdef HAVE_DIRECT_H
# include <direct.h>	/* to _getcwd */
#endif
#ifdef HAVE_DIR_H
# include <dir.h>	/* to declare findfirst() and findnext() */
#endif
#ifdef HAVE_IO_H
# include <io.h>	/* to declare open() */
#endif
#include "debug.h"
#include "routines.h"

#ifdef TRAP_MEMORY_CALLS
# include "safe_malloc.h"
#endif

/*
*   MACROS
*/
#ifndef TMPDIR
# define TMPDIR "/tmp"
#endif

/*  File type tests.
 */
#ifndef S_ISREG
# if defined (S_IFREG) && ! defined (AMIGA)
#  define S_ISREG(mode)	    ((mode) & S_IFREG)
# else
#  define S_ISREG(mode)	    TRUE	/* assume regular file */
# endif
#endif

#ifndef S_ISLNK
# ifdef S_IFLNK
#  define S_ISLNK(mode)	    (((mode) & S_IFMT) == S_IFLNK)
# else
#  define S_ISLNK(mode)	    FALSE	/* assume no soft links */
# endif
#endif

#ifndef S_ISDIR
# ifdef S_IFDIR
#  define S_ISDIR(mode)	    (((mode) & S_IFMT) == S_IFDIR)
# else
#  define S_ISDIR(mode)	    FALSE	/* assume no soft links */
# endif
#endif

#ifndef S_IFMT
# define S_IFMT 0
#endif

#ifndef S_IXUSR
# define S_IXUSR 0
#endif
#ifndef S_IXGRP
# define S_IXGRP 0
#endif
#ifndef S_IXOTH
# define S_IXOTH 0
#endif

#ifndef S_IRUSR
# define S_IRUSR 0400
#endif
#ifndef S_IWUSR
# define S_IWUSR 0200
#endif

#ifndef S_ISUID
# define S_ISUID 0
#endif

/*  Hack for rediculous practice of Microsoft Visual C++.
 */
#if defined (WIN32)
# if defined (_MSC_VER)
#  define stat    _stat
#  define getcwd  _getcwd
#  define currentdrive() (_getdrive() + 'A' - 1)
#  define PATH_MAX  _MAX_PATH
# elif defined (__BORLANDC__)
#  define PATH_MAX  MAXPATH
#  define currentdrive() (getdisk() + 'A')
# elif defined (DJGPP)
#  define currentdrive() (getdisk() + 'A')
# else
#  define currentdrive() 'C'
# endif
#endif

#ifndef PATH_MAX
# define PATH_MAX 256
#endif

/*
 *  Miscellaneous macros
 */
#define selected(var,feature)	(((int)(var) & (int)(feature)) == (int)feature)

/*
*   DATA DEFINITIONS
*/
#if defined (MSDOS_STYLE_PATH)
const char *const PathDelimiters = ":/\\";
#elif defined (VMS)
const char *const PathDelimiters = ":]>";
#endif

char *CurrentDirectory;

static const char *ExecutableProgram;
static const char *ExecutableName;

/*
*   FUNCTION PROTOTYPES
*/
#ifdef NEED_PROTO_STAT
extern int stat (const char *, struct stat *);
#endif
#ifdef NEED_PROTO_LSTAT
extern int lstat (const char *, struct stat *);
#endif
#if defined (MSDOS) || defined (WIN32) || defined (VMS) || defined (__EMX__) || defined (AMIGA)
# define lstat(fn,buf) stat(fn,buf)
#endif

/*
*   FUNCTION DEFINITIONS
*/

extern void freeRoutineResources (void)
{
    if (CurrentDirectory != NULL)
	eFree (CurrentDirectory);
}

extern void setExecutableName (const char *const path)
{
    ExecutableProgram = path;
    ExecutableName = baseFilename (path);
#ifdef VAXC
{
    /* remove filetype from executable name */
    char *p = strrchr (ExecutableName, '.');
    if (p != NULL)
	*p = '\0';
}
#endif
}

extern const char *getExecutableName (void)
{
    return ExecutableName;
}

extern void error (const errorSelection selection,
		   const char *const format, ...)
{
    va_list ap;

    va_start (ap, format);
    fprintf (errout, "%s: %s", getExecutableName (),
	    selected (selection, WARNING) ? "Warning: " : "");
    vfprintf (errout, format, ap);
    if (selected (selection, PERROR))
#ifdef HAVE_STRERROR
	fprintf (errout, " : %s", strerror (errno));
#else
	perror (" ");
#endif
    fputs ("\n", errout);
    va_end (ap);
    if (selected (selection, FATAL))
	exit (1);
}

/*
 *  Memory allocation functions
 */

extern void *eMalloc (const size_t size)
{
    void *buffer = malloc (size);

    if (buffer == NULL)
	error (FATAL, "out of memory");

    return buffer;
}

extern void *eCalloc (const size_t count, const size_t size)
{
    void *buffer = calloc (count, size);

    if (buffer == NULL)
	error (FATAL, "out of memory");

    return buffer;
}

extern void *eRealloc (void *const ptr, const size_t size)
{
    void *buffer;
    if (ptr == NULL)
	buffer = eMalloc (size);
    else
    {
	buffer = realloc (ptr, size);
	if (buffer == NULL)
	    error (FATAL, "out of memory");
    }
    return buffer;
}

extern void eFree (void *const ptr)
{
    Assert (ptr != NULL);
    free (ptr);
}

/*
 *  String manipulation functions
 */

/*
 * Compare two strings, ignoring case.
 * Return 0 for match, < 0 for smaller, > 0 for bigger
 * Make sure case is folded to uppercase in comparison (like for 'sort -f')
 * This makes a difference when one of the chars lies between upper and lower
 * ie. one of the chars [ \ ] ^ _ ` for ascii. (The '_' in particular !)
 */
extern int struppercmp (const char *s1, const char *s2)
{
    int result;
    do
    {
	result = toupper ((int) *s1) - toupper ((int) *s2);
    } while (result == 0  &&  *s1++ != '\0'  &&  *s2++ != '\0');
    return result;
}

extern int strnuppercmp (const char *s1, const char *s2, size_t n)
{
    int result;
    do
    {
	result = toupper ((int) *s1) - toupper ((int) *s2);
    } while (result == 0  &&  --n > 0  &&  *s1++ != '\0'  &&  *s2++ != '\0');
    return result;
}

#ifndef HAVE_STRSTR
extern char* strstr (const char *str, const char *substr)
{
    const size_t length = strlen (substr);
    const char *match = NULL;
    const char *p;

    for (p = str  ;  *p != '\0'  &&  match == NULL  ;  ++p)
	if (strncmp (p, substr, length) == 0)
	    match = p;
    return (char*) match;
}
#endif

extern char* eStrdup (const char* str)
{
    char* result = xMalloc (strlen (str) + 1, char);
    strcpy (result, str);
    return result;
}

extern void toLowerString (char* str)
{
    while (*str != '\0')
    {
	*str = tolower ((int) *str);
	++str;
    }
}

extern void toUpperString (char* str)
{
    while (*str != '\0')
    {
	*str = toupper ((int) *str);
	++str;
    }
}

/*  Newly allocated string containing lower case conversion of a string.
 */
extern char* newLowerString (const char* str)
{
    char* const result = xMalloc (strlen (str) + 1, char);
    int i = 0;
    do
	result [i] = tolower ((int) str [i]);
    while (str [i++] != '\0');
    return result;
}

/*  Newly allocated string containing upper case conversion of a string.
 */
extern char* newUpperString (const char* str)
{
    char* const result = xMalloc (strlen (str) + 1, char);
    int i = 0;
    do
	result [i] = toupper ((int) str [i]);
    while (str [i++] != '\0');
    return result;
}

/*
 * File system functions
 */

extern void setCurrentDirectory (void)
{
#ifndef AMIGA
    char* buf;
#endif
    if (CurrentDirectory == NULL)
	CurrentDirectory = xMalloc ((size_t) (PATH_MAX + 1), char);
#ifdef AMIGA
    strcpy (CurrentDirectory, ".");
#else
    buf = getcwd (CurrentDirectory, PATH_MAX);
    if (buf == NULL)
	perror ("");
#endif
    if (CurrentDirectory [strlen (CurrentDirectory) - (size_t) 1] !=
	    PATH_SEPARATOR)
    {
	sprintf (CurrentDirectory + strlen (CurrentDirectory), "%c",
		OUTPUT_PATH_SEPARATOR);
    }
}

#ifdef AMIGA
static boolean isAmigaDirectory (const char *const name)
{
    boolean result = FALSE;
    struct FileInfoBlock *const fib = xMalloc (1, struct FileInfoBlock);
    if (fib != NULL)
    {
	const BPTR flock = Lock ((UBYTE *) name, (long) ACCESS_READ);

	if (flock != (BPTR) NULL)
	{
	    if (Examine (flock, fib))
		result = ((fib->fib_DirEntryType >= 0) ? TRUE : FALSE);
	    UnLock (flock);
	}
	eFree (fib);
    }
    return result;
}
#endif

/* For caching of stat() calls */
extern fileStatus *eStat (const char *const fileName)
{
    struct stat status;
    static fileStatus file;
    if (file.name == NULL  ||  strcmp (fileName, file.name) != 0)
    {
	if (file.name != NULL)
	    eFree (file.name);
	file.name = eStrdup (fileName);
	if (lstat (file.name, &status) != 0)
	    file.exists = FALSE;
	else
	{
	    file.isSymbolicLink = (boolean) S_ISLNK (status.st_mode);
	    if (file.isSymbolicLink  &&  stat (file.name, &status) != 0)
		file.exists = FALSE;
	    else
	    {
		file.exists = TRUE;
#ifdef AMIGA
		file.isDirectory = isAmigaDirectory (file.name);
#else
		file.isDirectory = (boolean) S_ISDIR (status.st_mode);
#endif
		file.isNormalFile = (boolean) (S_ISREG (status.st_mode));

⌨️ 快捷键说明

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