34#if defined (HAVE_SYS_TYPES_H)
35# include <sys/types.h>
37# if defined (HAVE_TYPES_H)
73# define S_ISREG(mode) ((mode) & S_IFREG)
79# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
81# define S_ISLNK(mode) false
87# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
89# define S_ISDIR(mode) false
125# if defined (_MSC_VER) || defined (__MINGW32__)
129# define getcwd _getcwd
130# define currentdrive() (_getdrive() + 'A' - 1)
132# define currentdrive() 'C'
148#if defined (MSDOS_STYLE_PATH)
149const char *
const PathDelimiters =
":/\\";
160#ifdef NEED_PROTO_STAT
161extern int stat (
const char *,
struct stat *);
163#ifdef NEED_PROTO_LSTAT
164extern int lstat (
const char *,
struct stat *);
167# define lstat(fn,buf) stat(fn,buf)
208 return tolower( c1 ) == tolower( c2 );
220 void *buffer = malloc (size);
222 if (buffer ==
NULL && size != 0)
230 void *buffer = calloc (
count, size);
232 if (buffer ==
NULL &&
count != 0 && size != 0)
245 buffer = realloc (
ptr, size);
246 if (buffer ==
NULL && size != 0)
288 result = toupper ((
int) *s1) - toupper ((
int) *s2);
289 }
while (result == 0 && *s1++ !=
'\0' && *s2++ !=
'\0');
298 result = toupper ((
int) *s1) - toupper ((
int) *s2);
299 }
while (result == 0 && --n > 0 && *s1++ !=
'\0' && *s2++ !=
'\0');
304extern char*
strstr (
const char *str,
const char *substr)
306 const size_t length = strlen (substr);
309 for (p = str ; *p !=
'\0' ; ++p)
310 if (strncmp (p, substr, length) == 0)
316extern char*
strrstr (
const char *str,
const char *substr)
318 const size_t length = strlen (substr);
321 for (p = str + strlen(str) - length ; p >= str ; --p)
322 if (strncmp (p, substr, length) == 0)
329 char* result =
xMalloc (strlen (str) + 1,
char);
330 strcpy (result, str);
336 char* result =
xMalloc (len + 1,
char);
337 strncpy (result, str, len);
346 *str = tolower ((
int) *str);
355 *str = toupper ((
int) *str);
364 char*
const result =
xMalloc (strlen (str) + 1,
char);
367 result [i] = tolower ((
int) str [i]);
368 while (str [i++] !=
'\0');
376 char*
const result =
xMalloc (strlen (str) + 1,
char);
379 result [i] = toupper ((
int) str [i]);
380 while (str [i++] !=
'\0');
389extern bool strToULong(
const char *
const str,
int base,
unsigned long *value)
394 *value = strtoul (str, &endptr, base);
395 return *endptr ==
'\0' && str != endptr &&
errno == 0;
403extern bool strToLong(
const char *
const str,
int base,
long *value)
408 *value = strtol (str, &endptr, base);
409 return *endptr ==
'\0' && str != endptr &&
errno == 0;
412extern bool strToUInt(
const char *
const str,
int base,
unsigned int *value)
414 unsigned long ulong_value;
416 if(!
strToULong(str, base, &ulong_value) || ulong_value > UINT_MAX)
419 *value = (
unsigned int) ulong_value;
423extern bool strToInt(
const char *
const str,
int base,
int *value)
427 if(!
strToLong(str, base, &long_value) || long_value > INT_MAX || long_value < INT_MIN)
430 *value = (int) long_value;
459 if (file.name ==
NULL || strcmp (fileName, file.name) != 0)
462 file.name =
eStrdup (fileName);
463 if (lstat (file.name, &status) != 0)
467 file.isSymbolicLink = (bool)
S_ISLNK (status.st_mode);
468 if (file.isSymbolicLink && stat (file.name, &status) != 0)
473 file.isDirectory = (
bool)
S_ISDIR (status.st_mode);
474 file.isNormalFile = (bool) (S_ISREG (status.st_mode));
475 file.isExecutable = (bool) ((status.st_mode &
477 file.isSetuid = (bool) ((status.st_mode &
S_ISUID) != 0);
478 file.isSetgid = (bool) ((status.st_mode &
S_ISGID) != 0);
479 file.size = status.st_size;
515 path [strlen (path) - 1] =
'\0';
516 while (! result && strlen (path) > (
size_t) 1)
519 if (separator ==
NULL)
521 else if (separator == path)
522 *(separator + 1) =
'\0';
539#if defined (MSDOS_STYLE_PATH)
540 result = (bool) (strchr (PathDelimiters, c) !=
NULL);
549#if defined (MSDOS_STYLE_PATH)
550 return strpbrk (s, PathDelimiters);
558#if defined (MSDOS_STYLE_PATH)
559 const char *last =
NULL;
574# if defined (MSDOS_STYLE_PATH)
576 for (p = path ; *p !=
'\0' ; ++p)
582extern bool isSameFile (
const char *
const name1,
const char *
const name2)
585#if defined (HAVE_STAT_ST_INO)
586 struct stat stat1, stat2;
588 if (stat (name1, &stat1) == 0 && stat (name2, &stat2) == 0)
589 result = (bool) (stat1.st_ino == stat2.st_ino);
596# if defined (CASE_INSENSITIVE_FILENAMES)
599 result = (bool) (strcmp (n1, n2) == 0);
610#if defined (MSDOS_STYLE_PATH)
616 for (i = 0 ; i < strlen (PathDelimiters) ; ++i)
624 for (p = filePath ; *p !=
'\0' ; ++p)
629 else if (*p == PathDelimiters [i] && p >
tail)
633 const char *sep = strrchr (filePath, PathDelimiters [i]);
652 const char *extension;
653 const char *pDelimiter;
656 pDelimiter = strrchr (base,
'.');
658 if (pDelimiter ==
NULL)
661 extension = pDelimiter + 1;
667 const char *
const templateExt)
669 const char *pDelimiter;
673 pDelimiter = strrchr (base, templateExt[0]);
675 if (pDelimiter && (strcmp (pDelimiter, templateExt) == 0))
677 shorten_base =
eStrndup (base, pDelimiter - base);
687#if defined (MSDOS_STYLE_PATH)
690 else if (isalpha (path [0]) && path [1] ==
':')
701 "%s: relative file names with drive letters not supported",
714 const char *
const path,
const char *
const file)
717 size_t len = strlen (path);
721 const int lastChar = path [len - 1];
736static char*
concat (
const char *s1,
const char *s2,
const char *s3)
738 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
739 char *result =
xMalloc (len1 + len2 + len3 + 1,
char);
742 strcpy (result + len1, s2);
743 strcpy (result + len1 + len2, s3);
744 result [len1 + len2 + len3] =
'\0';
759#ifdef MSDOS_STYLE_PATH
765 sprintf (drive,
"%c:", currentdrive ());
766 res =
concat (drive, file,
"");
777 while (slashp !=
NULL && slashp [0] !=
'\0')
779 if (slashp[1] ==
'.')
781 if (slashp [2] ==
'.' &&
790#ifdef MSDOS_STYLE_PATH
798 memmove (cp, slashp + 3, strlen (slashp + 3) + 1);
804 memmove (slashp, slashp + 2, strlen (slashp + 2) + 1);
819#ifdef MSDOS_STYLE_PATH
821 if (res [1] ==
':' && islower (res [0]))
822 res [0] = toupper (res [0]);
881 res =
xMalloc (3 * i + strlen (fp + 1) + 1,
char);
886 strcat (res, parent);
890 strcat (res, fp + 1);
902#if defined(HAVE_MKSTEMP)
903 const char *
const pattern =
"tags.XXXXXX";
904 const char *tmpdir =
NULL;
907 tmpdir = getenv (
"TMP");
910 tmpdir = getenv (
"TMPDIR");
914 name =
xMalloc (strlen (tmpdir) + 1 + strlen (pattern) + 1,
char);
923 for (i = 0; i < 5 && fd == -1; i++)
931#elif defined(HAVE_TEMPNAM)
932 const char *tmpdir =
NULL;
934 tmpdir = getenv (
"TMP");
938 name = tempnam (tmpdir,
"tags");
950 fp = fdopen (fd, mode);
#define DebugStatement(x)
void debugPrintf(const enum eDebugLevels level, const char *const format,...)
int mkstemp(char *template_name)
void error(const errorSelection selection, const char *const format,...)
#define CTAGS_ATTR_UNUSED
static bool tail(const char *cp)
#define strcasecmp(s1, s2)
MIO * mio_new_fp(FILE *fp, MIOFCloseFunc close_func)
mio_new_fp: @fp: An opened #FILE object @close_func: (allow-none): Function used to close @fp when th...
char * absoluteFilename(const char *file)
char * combinePathAndFile(const char *const path, const char *const file)
char * eStrndup(const char *str, size_t len)
static bool isPathSeparator(const int c)
bool doesFileExist(const char *const fileName)
bool strToUInt(const char *const str, int base, unsigned int *value)
bool strToInt(const char *const str, int base, int *value)
int struppercmp(const char *s1, const char *s2)
char * newLowerString(const char *str)
int strnuppercmp(const char *s1, const char *s2, size_t n)
void setExecutableName(const char *const path)
void * eMalloc(const size_t size)
static char * concat(const char *s1, const char *s2, const char *s3)
bool strToULong(const char *const str, int base, unsigned long *value)
const char * getExecutablePath(void)
void toLowerString(char *str)
static void canonicalizePath(char *const path)
bool isSameFile(const char *const name1, const char *const name2)
char * baseFilenameSansExtensionNew(const char *const fileName, const char *const templateExt)
char * newUpperString(const char *str)
void eFreeNoNullCheck(void *const ptr)
const char * fileExtension(const char *const fileName)
char * absoluteDirname(char *file)
char * strstr(const char *str, const char *substr)
void eFreeIndirect(void **ptr)
bool isRecursiveLink(const char *const dirName)
const char * getExecutableName(void)
static char * strSeparator(const char *s)
void * eRealloc(void *const ptr, const size_t size)
static const char * ExecutableName
static const char * ExecutableProgram
char * eStrdup(const char *str)
void setCurrentDirectory(void)
bool isAbsolutePath(const char *const path)
void eFree(void *const ptr)
bool doesExecutableExist(const char *const fileName)
fileStatus * eStat(const char *const fileName)
static char * strRSeparator(const char *s)
void eStatFree(fileStatus *status)
MIO * tempFile(const char *const mode, char **const pName)
const char * baseFilename(const char *const filePath)
void toUpperString(char *str)
bool strToLong(const char *const str, int base, long *value)
char * strrstr(const char *str, const char *substr)
void freeRoutineResources(void)
static bool fnmChEq(int c1, int c2)
void * eCalloc(const size_t count, const size_t size)
char * relativeFilename(const char *file, const char *dir)
#define OUTPUT_PATH_SEPARATOR
void vStringCopyS(vString *const string, const char *const s)
vString * vStringNew(void)
void vStringCatS(vString *const string, const char *const s)
char * vStringDeleteUnwrap(vString *const string)
static void vStringPut(vString *const string, const int c)