intl/icu/source/tools/toolutil/toolutil.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2 *******************************************************************************
     3 *
     4 *   Copyright (C) 1999-2013, International Business Machines
     5 *   Corporation and others.  All Rights Reserved.
     6 *
     7 *******************************************************************************
     8 *   file name:  toolutil.c
     9 *   encoding:   US-ASCII
    10 *   tab size:   8 (not used)
    11 *   indentation:4
    12 *
    13 *   created on: 1999nov19
    14 *   created by: Markus W. Scherer
    15 *
    16 *	6/25/08 - Added Cygwin specific code in uprv_mkdir - Brian Rower
    17 *	
    18 *   This file contains utility functions for ICU tools like genccode.
    19 */
    21 #if U_PLATFORM == U_PF_MINGW
    22 // *cough* - for struct stat
    23 #ifdef __STRICT_ANSI__
    24 #undef __STRICT_ANSI__
    25 #endif
    26 #endif
    28 #include <stdio.h>
    29 #include <sys/stat.h>
    30 #include "unicode/utypes.h"
    32 #ifndef U_TOOLUTIL_IMPLEMENTATION
    33 #error U_TOOLUTIL_IMPLEMENTATION not set - must be set for all ICU source files in common/ - see http://userguide.icu-project.org/howtouseicu
    34 #endif
    36 #if U_PLATFORM_USES_ONLY_WIN32_API
    37 #   define VC_EXTRALEAN
    38 #   define WIN32_LEAN_AND_MEAN
    39 #   define NOUSER
    40 #   define NOSERVICE
    41 #   define NOIME
    42 #   define NOMCX
    43 #   if U_PLATFORM == U_PF_MINGW
    44 #     define __NO_MINGW_LFS /* gets around missing 'off64_t' */
    45 #   endif
    46 #   include <windows.h>
    47 #   include <direct.h>
    48 #else
    49 #   include <sys/stat.h>
    50 #   include <sys/types.h>
    51 #endif
    53 /* In MinGW environment, io.h needs to be included for _mkdir() */
    54 #if U_PLATFORM == U_PF_MINGW
    55 #include <io.h>
    56 #endif
    58 #include <errno.h>
    60 #include "unicode/errorcode.h"
    61 #include "unicode/putil.h"
    62 #include "cmemory.h"
    63 #include "cstring.h"
    64 #include "toolutil.h"
    65 #include "unicode/ucal.h"
    67 U_NAMESPACE_BEGIN
    69 IcuToolErrorCode::~IcuToolErrorCode() {
    70     // Safe because our handleFailure() does not throw exceptions.
    71     if(isFailure()) { handleFailure(); }
    72 }
    74 void IcuToolErrorCode::handleFailure() const {
    75     fprintf(stderr, "error at %s: %s\n", location, errorName());
    76     exit(errorCode);
    77 }
    79 U_NAMESPACE_END
    81 static int32_t currentYear = -1;
    83 U_CAPI int32_t U_EXPORT2 getCurrentYear() {
    84 #if !UCONFIG_NO_FORMATTING
    85     UErrorCode status=U_ZERO_ERROR;    
    86     UCalendar *cal = NULL;
    88     if(currentYear == -1) {
    89         cal = ucal_open(NULL, -1, NULL, UCAL_TRADITIONAL, &status);
    90         ucal_setMillis(cal, ucal_getNow(), &status);
    91         currentYear = ucal_get(cal, UCAL_YEAR, &status);
    92         ucal_close(cal);
    93     }
    94 #else
    95     /* No formatting- no way to set the current year. */
    96 #endif
    97     return currentYear;
    98 }
   101 U_CAPI const char * U_EXPORT2
   102 getLongPathname(const char *pathname) {
   103 #if U_PLATFORM_USES_ONLY_WIN32_API
   104     /* anticipate problems with "short" pathnames */
   105     static WIN32_FIND_DATAA info;
   106     HANDLE file=FindFirstFileA(pathname, &info);
   107     if(file!=INVALID_HANDLE_VALUE) {
   108         if(info.cAlternateFileName[0]!=0) {
   109             /* this file has a short name, get and use the long one */
   110             const char *basename=findBasename(pathname);
   111             if(basename!=pathname) {
   112                 /* prepend the long filename with the original path */
   113                 uprv_memmove(info.cFileName+(basename-pathname), info.cFileName, uprv_strlen(info.cFileName)+1);
   114                 uprv_memcpy(info.cFileName, pathname, basename-pathname);
   115             }
   116             pathname=info.cFileName;
   117         }
   118         FindClose(file);
   119     }
   120 #endif
   121     return pathname;
   122 }
   124 U_CAPI const char * U_EXPORT2
   125 findDirname(const char *path, char *buffer, int32_t bufLen, UErrorCode* status) {
   126   if(U_FAILURE(*status)) return NULL;
   127   const char *resultPtr = NULL;
   128   int32_t resultLen = 0;
   130   const char *basename=uprv_strrchr(path, U_FILE_SEP_CHAR);
   131 #if U_FILE_ALT_SEP_CHAR!=U_FILE_SEP_CHAR
   132   const char *basenameAlt=uprv_strrchr(path, U_FILE_ALT_SEP_CHAR);
   133   if(basenameAlt && (!basename || basename<basenameAlt)) {
   134     basename = basenameAlt;
   135   }
   136 #endif
   137   if(!basename) {
   138     /* no basename - return ''. */
   139     resultPtr = "";
   140     resultLen = 0;
   141   } else {
   142     resultPtr = path;
   143     resultLen = basename - path;
   144     if(resultLen<1) {
   145       resultLen = 1; /* '/' or '/a' -> '/' */
   146     }
   147   }
   149   if((resultLen+1) <= bufLen) {
   150     uprv_strncpy(buffer, resultPtr, resultLen);
   151     buffer[resultLen]=0;
   152     return buffer;
   153   } else {
   154     *status = U_BUFFER_OVERFLOW_ERROR;
   155     return NULL;
   156   }
   157 }
   159 U_CAPI const char * U_EXPORT2
   160 findBasename(const char *filename) {
   161     const char *basename=uprv_strrchr(filename, U_FILE_SEP_CHAR);
   163 #if U_FILE_ALT_SEP_CHAR!=U_FILE_SEP_CHAR
   164     if(basename==NULL) {
   165         /* Use lenient matching on Windows, which can accept either \ or /
   166            This is useful for environments like Win32+CygWin which have both.
   167         */
   168         basename=uprv_strrchr(filename, U_FILE_ALT_SEP_CHAR);
   169     }
   170 #endif
   172     if(basename!=NULL) {
   173         return basename+1;
   174     } else {
   175         return filename;
   176     }
   177 }
   179 U_CAPI void U_EXPORT2
   180 uprv_mkdir(const char *pathname, UErrorCode *status) {
   182     int retVal = 0;
   183 #if U_PLATFORM_USES_ONLY_WIN32_API
   184     retVal = _mkdir(pathname);
   185 #else
   186     retVal = mkdir(pathname, S_IRWXU | (S_IROTH | S_IXOTH) | (S_IROTH | S_IXOTH));
   187 #endif
   188     if (retVal && errno != EEXIST) {
   189 #if U_PF_MINGW <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
   190         /*if using Cygwin and the mkdir says it failed...check if the directory already exists..*/
   191         /* if it does...don't give the error, if it does not...give the error - Brian Rower - 6/25/08 */
   192         struct stat st;
   194         if(stat(pathname,&st) != 0)
   195         {
   196             *status = U_FILE_ACCESS_ERROR;
   197         }
   198 #else
   199         *status = U_FILE_ACCESS_ERROR;
   200 #endif
   201     }
   202 }
   204 #if !UCONFIG_NO_FILE_IO
   205 U_CAPI UBool U_EXPORT2
   206 uprv_fileExists(const char *file) {
   207   struct stat stat_buf;
   208   if (stat(file, &stat_buf) == 0) {
   209     return TRUE;
   210   } else {
   211     return FALSE;
   212   }
   213 }
   214 #endif
   216 /*U_CAPI UDate U_EXPORT2
   217 uprv_getModificationDate(const char *pathname, UErrorCode *status)
   218 {
   219     if(U_FAILURE(*status)) {
   220         return;
   221     }
   222     //  TODO: handle case where stat is not available
   223     struct stat st;
   225     if(stat(pathname,&st) != 0)
   226     {
   227         *status = U_FILE_ACCESS_ERROR;
   228     } else {
   229         return st.st_mtime;
   230     }
   231 }
   232 */
   234 /* tool memory helper ------------------------------------------------------- */
   236 struct UToolMemory {
   237     char name[64];
   238     int32_t capacity, maxCapacity, size, idx;
   239     void *array;
   240     UAlignedMemory staticArray[1];
   241 };
   243 U_CAPI UToolMemory * U_EXPORT2
   244 utm_open(const char *name, int32_t initialCapacity, int32_t maxCapacity, int32_t size) {
   245     UToolMemory *mem;
   247     if(maxCapacity<initialCapacity) {
   248         maxCapacity=initialCapacity;
   249     }
   251     mem=(UToolMemory *)uprv_malloc(sizeof(UToolMemory)+initialCapacity*size);
   252     if(mem==NULL) {
   253         fprintf(stderr, "error: %s - out of memory\n", name);
   254         exit(U_MEMORY_ALLOCATION_ERROR);
   255     }
   256     mem->array=mem->staticArray;
   258     uprv_strcpy(mem->name, name);
   259     mem->capacity=initialCapacity;
   260     mem->maxCapacity=maxCapacity;
   261     mem->size=size;
   262     mem->idx=0;
   263     return mem;
   264 }
   266 U_CAPI void U_EXPORT2
   267 utm_close(UToolMemory *mem) {
   268     if(mem!=NULL) {
   269         if(mem->array!=mem->staticArray) {
   270             uprv_free(mem->array);
   271         }
   272         uprv_free(mem);
   273     }
   274 }
   277 U_CAPI void * U_EXPORT2
   278 utm_getStart(UToolMemory *mem) {
   279     return (char *)mem->array;
   280 }
   282 U_CAPI int32_t U_EXPORT2
   283 utm_countItems(UToolMemory *mem) {
   284     return mem->idx;
   285 }
   288 static UBool
   289 utm_hasCapacity(UToolMemory *mem, int32_t capacity) {
   290     if(mem->capacity<capacity) {
   291         int32_t newCapacity;
   293         if(mem->maxCapacity<capacity) {
   294             fprintf(stderr, "error: %s - trying to use more than maxCapacity=%ld units\n",
   295                     mem->name, (long)mem->maxCapacity);
   296             exit(U_MEMORY_ALLOCATION_ERROR);
   297         }
   299         /* try to allocate a larger array */
   300         if(capacity>=2*mem->capacity) {
   301             newCapacity=capacity;
   302         } else if(mem->capacity<=mem->maxCapacity/3) {
   303             newCapacity=2*mem->capacity;
   304         } else {
   305             newCapacity=mem->maxCapacity;
   306         }
   308         if(mem->array==mem->staticArray) {
   309             mem->array=uprv_malloc(newCapacity*mem->size);
   310             if(mem->array!=NULL) {
   311                 uprv_memcpy(mem->array, mem->staticArray, mem->idx*mem->size);
   312             }
   313         } else {
   314             mem->array=uprv_realloc(mem->array, newCapacity*mem->size);
   315         }
   317         if(mem->array==NULL) {
   318             fprintf(stderr, "error: %s - out of memory\n", mem->name);
   319             exit(U_MEMORY_ALLOCATION_ERROR);
   320         }
   321         mem->capacity=newCapacity;
   322     }
   324     return TRUE;
   325 }
   327 U_CAPI void * U_EXPORT2
   328 utm_alloc(UToolMemory *mem) {
   329     char *p=NULL;
   330     int32_t oldIndex=mem->idx;
   331     int32_t newIndex=oldIndex+1;
   332     if(utm_hasCapacity(mem, newIndex)) {
   333         p=(char *)mem->array+oldIndex*mem->size;
   334         mem->idx=newIndex;
   335         uprv_memset(p, 0, mem->size);
   336     }
   337     return p;
   338 }
   340 U_CAPI void * U_EXPORT2
   341 utm_allocN(UToolMemory *mem, int32_t n) {
   342     char *p=NULL;
   343     int32_t oldIndex=mem->idx;
   344     int32_t newIndex=oldIndex+n;
   345     if(utm_hasCapacity(mem, newIndex)) {
   346         p=(char *)mem->array+oldIndex*mem->size;
   347         mem->idx=newIndex;
   348         uprv_memset(p, 0, n*mem->size);
   349     }
   350     return p;
   351 }

mercurial