1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/tools/toolutil/filetools.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,134 @@ 1.4 +/****************************************************************************** 1.5 + * Copyright (C) 2009-2013, International Business Machines 1.6 + * Corporation and others. All Rights Reserved. 1.7 + ******************************************************************************* 1.8 + */ 1.9 + 1.10 +#if U_PLATFORM == U_PF_MINGW 1.11 +// *cough* - for struct stat 1.12 +#ifdef __STRICT_ANSI__ 1.13 +#undef __STRICT_ANSI__ 1.14 +#endif 1.15 +#endif 1.16 + 1.17 +#include "filetools.h" 1.18 +#include "filestrm.h" 1.19 +#include "cstring.h" 1.20 +#include "unicode/putil.h" 1.21 +#include "putilimp.h" 1.22 + 1.23 +#include <stdio.h> 1.24 +#include <stdlib.h> 1.25 +#include <sys/stat.h> 1.26 +#include <time.h> 1.27 +#include <string.h> 1.28 + 1.29 +#if U_HAVE_DIRENT_H 1.30 +#include <dirent.h> 1.31 +typedef struct dirent DIRENT; 1.32 + 1.33 +#define MAX_PATH_SIZE 4096 /* Set the limit for the size of the path. */ 1.34 + 1.35 +#define SKIP1 "." 1.36 +#define SKIP2 ".." 1.37 +#endif 1.38 + 1.39 +static int32_t whichFileModTimeIsLater(const char *file1, const char *file2); 1.40 + 1.41 +/* 1.42 + * Goes through the given directory recursive to compare each file's modification time with that of the file given. 1.43 + * Also can be given just one file to check against. Default value for isDir is FALSE. 1.44 + */ 1.45 +U_CAPI UBool U_EXPORT2 1.46 +isFileModTimeLater(const char *filePath, const char *checkAgainst, UBool isDir) { 1.47 + UBool isLatest = TRUE; 1.48 + 1.49 + if (filePath == NULL || checkAgainst == NULL) { 1.50 + return FALSE; 1.51 + } 1.52 + 1.53 + if (isDir == TRUE) { 1.54 +#if U_HAVE_DIRENT_H 1.55 + DIR *pDir = NULL; 1.56 + if ((pDir= opendir(checkAgainst)) != NULL) { 1.57 + DIR *subDirp = NULL; 1.58 + DIRENT *dirEntry = NULL; 1.59 + 1.60 + while ((dirEntry = readdir(pDir)) != NULL) { 1.61 + if (uprv_strcmp(dirEntry->d_name, SKIP1) != 0 && uprv_strcmp(dirEntry->d_name, SKIP2) != 0) { 1.62 + char newpath[MAX_PATH_SIZE] = ""; 1.63 + uprv_strcpy(newpath, checkAgainst); 1.64 + uprv_strcat(newpath, U_FILE_SEP_STRING); 1.65 + uprv_strcat(newpath, dirEntry->d_name); 1.66 + 1.67 + if ((subDirp = opendir(newpath)) != NULL) { 1.68 + /* If this new path is a directory, make a recursive call with the newpath. */ 1.69 + closedir(subDirp); 1.70 + isLatest = isFileModTimeLater(filePath, newpath, isDir); 1.71 + if (!isLatest) { 1.72 + break; 1.73 + } 1.74 + } else { 1.75 + int32_t latest = whichFileModTimeIsLater(filePath, newpath); 1.76 + if (latest < 0 || latest == 2) { 1.77 + isLatest = FALSE; 1.78 + break; 1.79 + } 1.80 + } 1.81 + 1.82 + } 1.83 + } 1.84 + closedir(pDir); 1.85 + } else { 1.86 + fprintf(stderr, "Unable to open directory: %s\n", checkAgainst); 1.87 + return FALSE; 1.88 + } 1.89 +#endif 1.90 + } else { 1.91 + if (T_FileStream_file_exists(checkAgainst)) { 1.92 + int32_t latest = whichFileModTimeIsLater(filePath, checkAgainst); 1.93 + if (latest < 0 || latest == 2) { 1.94 + isLatest = FALSE; 1.95 + } 1.96 + } else { 1.97 + isLatest = FALSE; 1.98 + } 1.99 + } 1.100 + 1.101 + return isLatest; 1.102 +} 1.103 + 1.104 +/* Compares the mod time of both files returning a number indicating which one is later. -1 if error ocurs. */ 1.105 +static int32_t whichFileModTimeIsLater(const char *file1, const char *file2) { 1.106 + int32_t result = 0; 1.107 + struct stat stbuf1, stbuf2; 1.108 + 1.109 + if (stat(file1, &stbuf1) == 0 && stat(file2, &stbuf2) == 0) { 1.110 + time_t modtime1, modtime2; 1.111 + double diff; 1.112 + 1.113 + modtime1 = stbuf1.st_mtime; 1.114 + modtime2 = stbuf2.st_mtime; 1.115 + 1.116 + diff = difftime(modtime1, modtime2); 1.117 + if (diff < 0.0) { 1.118 + result = 2; 1.119 + } else if (diff > 0.0) { 1.120 + result = 1; 1.121 + } 1.122 + 1.123 + } else { 1.124 + fprintf(stderr, "Unable to get stats from file: %s or %s\n", file1, file2); 1.125 + result = -1; 1.126 + } 1.127 + 1.128 + return result; 1.129 +} 1.130 + 1.131 +/* Swap the file separater character given with the new one in the file path. */ 1.132 +U_CAPI void U_EXPORT2 1.133 +swapFileSepChar(char *filePath, const char oldFileSepChar, const char newFileSepChar) { 1.134 + for (int32_t i = 0, length = uprv_strlen(filePath); i < length; i++) { 1.135 + filePath[i] = (filePath[i] == oldFileSepChar ) ? newFileSepChar : filePath[i]; 1.136 + } 1.137 +}