1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*******************************************************************************
3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
4fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius*   Copyright (C) 1999-2014, International Business Machines
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*******************************************************************************
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   file name:  toolutil.c
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   encoding:   US-ASCII
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   tab size:   8 (not used)
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   indentation:4
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   created on: 1999nov19
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   created by: Markus W. Scherer
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
16db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru*	6/25/08 - Added Cygwin specific code in uprv_mkdir - Brian Rower
17db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru*
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   This file contains utility functions for ICU tools like genccode.
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
21fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/platform.h"
2259d709d503bab6e2b61931737e662dd293b40578ccornelius#if U_PLATFORM == U_PF_MINGW
2359d709d503bab6e2b61931737e662dd293b40578ccornelius// *cough* - for struct stat
2459d709d503bab6e2b61931737e662dd293b40578ccornelius#ifdef __STRICT_ANSI__
2559d709d503bab6e2b61931737e662dd293b40578ccornelius#undef __STRICT_ANSI__
2659d709d503bab6e2b61931737e662dd293b40578ccornelius#endif
2759d709d503bab6e2b61931737e662dd293b40578ccornelius#endif
2859d709d503bab6e2b61931737e662dd293b40578ccornelius
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h>
30db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru#include <sys/stat.h>
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#ifndef U_TOOLUTIL_IMPLEMENTATION
3483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#error U_TOOLUTIL_IMPLEMENTATION not set - must be set for all ICU source files in common/ - see http://userguide.icu-project.org/howtouseicu
3583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#endif
3683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius
3783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#   define VC_EXTRALEAN
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#   define WIN32_LEAN_AND_MEAN
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#   define NOUSER
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#   define NOSERVICE
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#   define NOIME
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#   define NOMCX
4459d709d503bab6e2b61931737e662dd293b40578ccornelius#   if U_PLATFORM == U_PF_MINGW
4559d709d503bab6e2b61931737e662dd293b40578ccornelius#     define __NO_MINGW_LFS /* gets around missing 'off64_t' */
4659d709d503bab6e2b61931737e662dd293b40578ccornelius#   endif
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#   include <windows.h>
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#   include <direct.h>
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#   include <sys/stat.h>
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#   include <sys/types.h>
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
5327f654740f2a26ad62a5c155af9199af9e69b889claireho
5427f654740f2a26ad62a5c155af9199af9e69b889claireho/* In MinGW environment, io.h needs to be included for _mkdir() */
5583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#if U_PLATFORM == U_PF_MINGW
5627f654740f2a26ad62a5c155af9199af9e69b889claireho#include <io.h>
5727f654740f2a26ad62a5c155af9199af9e69b889claireho#endif
5827f654740f2a26ad62a5c155af9199af9e69b889claireho
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <errno.h>
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
6150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/errorcode.h"
6250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/putil.h"
6350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cmemory.h"
6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cstring.h"
6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "toolutil.h"
6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/ucal.h"
6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
6850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_BEGIN
6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
7050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoIcuToolErrorCode::~IcuToolErrorCode() {
7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // Safe because our handleFailure() does not throw exceptions.
7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(isFailure()) { handleFailure(); }
7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
7550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid IcuToolErrorCode::handleFailure() const {
7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    fprintf(stderr, "error at %s: %s\n", location, errorName());
7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    exit(errorCode);
7850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
7950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
8050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_END
8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
827d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Querustatic int32_t currentYear = -1;
837d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru
847d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 getCurrentYear() {
857d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
867d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru    UErrorCode status=U_ZERO_ERROR;
877d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru    UCalendar *cal = NULL;
887d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru
897d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru    if(currentYear == -1) {
907d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru        cal = ucal_open(NULL, -1, NULL, UCAL_TRADITIONAL, &status);
917d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru        ucal_setMillis(cal, ucal_getNow(), &status);
927d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru        currentYear = ucal_get(cal, UCAL_YEAR, &status);
937d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru        ucal_close(cal);
947d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru    }
957d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru#else
9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /* No formatting- no way to set the current year. */
977d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru#endif
9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return currentYear;
997d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru}
1007d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru
1017d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char * U_EXPORT2
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerugetLongPathname(const char *pathname) {
10483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* anticipate problems with "short" pathnames */
1063d5f03535b3762504420499f55a5810325e5b539Jean-Baptiste Queru    static WIN32_FIND_DATAA info;
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    HANDLE file=FindFirstFileA(pathname, &info);
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(file!=INVALID_HANDLE_VALUE) {
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(info.cAlternateFileName[0]!=0) {
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* this file has a short name, get and use the long one */
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            const char *basename=findBasename(pathname);
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(basename!=pathname) {
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* prepend the long filename with the original path */
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                uprv_memmove(info.cFileName+(basename-pathname), info.cFileName, uprv_strlen(info.cFileName)+1);
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                uprv_memcpy(info.cFileName, pathname, basename-pathname);
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            pathname=info.cFileName;
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        FindClose(file);
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return pathname;
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char * U_EXPORT2
12650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehofindDirname(const char *path, char *buffer, int32_t bufLen, UErrorCode* status) {
12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  if(U_FAILURE(*status)) return NULL;
12850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  const char *resultPtr = NULL;
12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  int32_t resultLen = 0;
13050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  const char *basename=uprv_strrchr(path, U_FILE_SEP_CHAR);
13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if U_FILE_ALT_SEP_CHAR!=U_FILE_SEP_CHAR
13350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  const char *basenameAlt=uprv_strrchr(path, U_FILE_ALT_SEP_CHAR);
13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  if(basenameAlt && (!basename || basename<basenameAlt)) {
13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    basename = basenameAlt;
13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  }
13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  if(!basename) {
13983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    /* no basename - return ''. */
14083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    resultPtr = "";
14183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    resultLen = 0;
14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  } else {
14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    resultPtr = path;
14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    resultLen = basename - path;
14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(resultLen<1) {
14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      resultLen = 1; /* '/' or '/a' -> '/' */
14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
14850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  }
14950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
15050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  if((resultLen+1) <= bufLen) {
15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_strncpy(buffer, resultPtr, resultLen);
15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    buffer[resultLen]=0;
15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return buffer;
15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  } else {
15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    *status = U_BUFFER_OVERFLOW_ERROR;
15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return NULL;
15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  }
15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
16050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI const char * U_EXPORT2
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerufindBasename(const char *filename) {
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char *basename=uprv_strrchr(filename, U_FILE_SEP_CHAR);
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if U_FILE_ALT_SEP_CHAR!=U_FILE_SEP_CHAR
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(basename==NULL) {
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* Use lenient matching on Windows, which can accept either \ or /
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           This is useful for environments like Win32+CygWin which have both.
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        */
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        basename=uprv_strrchr(filename, U_FILE_ALT_SEP_CHAR);
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(basename!=NULL) {
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return basename+1;
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return filename;
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_mkdir(const char *pathname, UErrorCode *status) {
182db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int retVal = 0;
18483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    retVal = _mkdir(pathname);
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    retVal = mkdir(pathname, S_IRWXU | (S_IROTH | S_IXOTH) | (S_IROTH | S_IXOTH));
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (retVal && errno != EEXIST) {
19083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#if U_PF_MINGW <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        /*if using Cygwin and the mkdir says it failed...check if the directory already exists..*/
192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        /* if it does...don't give the error, if it does not...give the error - Brian Rower - 6/25/08 */
193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        struct stat st;
194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if(stat(pathname,&st) != 0)
196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        {
197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            *status = U_FILE_ACCESS_ERROR;
198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
199db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru#else
200db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru        *status = U_FILE_ACCESS_ERROR;
201db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru#endif
202db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru    }
203db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru}
204db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru
20559d709d503bab6e2b61931737e662dd293b40578ccornelius#if !UCONFIG_NO_FILE_IO
20659d709d503bab6e2b61931737e662dd293b40578ccorneliusU_CAPI UBool U_EXPORT2
20759d709d503bab6e2b61931737e662dd293b40578ccorneliusuprv_fileExists(const char *file) {
20859d709d503bab6e2b61931737e662dd293b40578ccornelius  struct stat stat_buf;
20959d709d503bab6e2b61931737e662dd293b40578ccornelius  if (stat(file, &stat_buf) == 0) {
21059d709d503bab6e2b61931737e662dd293b40578ccornelius    return TRUE;
21159d709d503bab6e2b61931737e662dd293b40578ccornelius  } else {
21259d709d503bab6e2b61931737e662dd293b40578ccornelius    return FALSE;
21359d709d503bab6e2b61931737e662dd293b40578ccornelius  }
21459d709d503bab6e2b61931737e662dd293b40578ccornelius}
21559d709d503bab6e2b61931737e662dd293b40578ccornelius#endif
21659d709d503bab6e2b61931737e662dd293b40578ccornelius
217db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru/*U_CAPI UDate U_EXPORT2
218db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queruuprv_getModificationDate(const char *pathname, UErrorCode *status)
219db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru{
220db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru    if(U_FAILURE(*status)) {
221db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru        return;
222db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru    }
223db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru    //  TODO: handle case where stat is not available
224db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru    struct stat st;
225db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru
226db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru    if(stat(pathname,&st) != 0)
227db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru    {
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *status = U_FILE_ACCESS_ERROR;
229db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru    } else {
230db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru        return st.st_mtime;
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
233db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru*/
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* tool memory helper ------------------------------------------------------- */
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustruct UToolMemory {
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char name[64];
239db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru    int32_t capacity, maxCapacity, size, idx;
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void *array;
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UAlignedMemory staticArray[1];
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UToolMemory * U_EXPORT2
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_open(const char *name, int32_t initialCapacity, int32_t maxCapacity, int32_t size) {
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UToolMemory *mem;
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(maxCapacity<initialCapacity) {
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        maxCapacity=initialCapacity;
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    mem=(UToolMemory *)uprv_malloc(sizeof(UToolMemory)+initialCapacity*size);
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(mem==NULL) {
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stderr, "error: %s - out of memory\n", name);
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        exit(U_MEMORY_ALLOCATION_ERROR);
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    mem->array=mem->staticArray;
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uprv_strcpy(mem->name, name);
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    mem->capacity=initialCapacity;
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    mem->maxCapacity=maxCapacity;
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    mem->size=size;
263db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru    mem->idx=0;
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return mem;
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_close(UToolMemory *mem) {
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(mem!=NULL) {
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(mem->array!=mem->staticArray) {
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            uprv_free(mem->array);
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uprv_free(mem);
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void * U_EXPORT2
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_getStart(UToolMemory *mem) {
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return (char *)mem->array;
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_countItems(UToolMemory *mem) {
285db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru    return mem->idx;
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_hasCapacity(UToolMemory *mem, int32_t capacity) {
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(mem->capacity<capacity) {
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t newCapacity;
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(mem->maxCapacity<capacity) {
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stderr, "error: %s - trying to use more than maxCapacity=%ld units\n",
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    mem->name, (long)mem->maxCapacity);
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            exit(U_MEMORY_ALLOCATION_ERROR);
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* try to allocate a larger array */
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(capacity>=2*mem->capacity) {
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            newCapacity=capacity;
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if(mem->capacity<=mem->maxCapacity/3) {
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            newCapacity=2*mem->capacity;
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            newCapacity=mem->maxCapacity;
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(mem->array==mem->staticArray) {
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            mem->array=uprv_malloc(newCapacity*mem->size);
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(mem->array!=NULL) {
312db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru                uprv_memcpy(mem->array, mem->staticArray, mem->idx*mem->size);
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            mem->array=uprv_realloc(mem->array, newCapacity*mem->size);
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(mem->array==NULL) {
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stderr, "error: %s - out of memory\n", mem->name);
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            exit(U_MEMORY_ALLOCATION_ERROR);
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        mem->capacity=newCapacity;
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return TRUE;
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void * U_EXPORT2
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_alloc(UToolMemory *mem) {
33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char *p=NULL;
33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t oldIndex=mem->idx;
33250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t newIndex=oldIndex+1;
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(utm_hasCapacity(mem, newIndex)) {
33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        p=(char *)mem->array+oldIndex*mem->size;
335db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru        mem->idx=newIndex;
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uprv_memset(p, 0, mem->size);
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return p;
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void * U_EXPORT2
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_allocN(UToolMemory *mem, int32_t n) {
34350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char *p=NULL;
34450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t oldIndex=mem->idx;
34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t newIndex=oldIndex+n;
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(utm_hasCapacity(mem, newIndex)) {
34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        p=(char *)mem->array+oldIndex*mem->size;
348db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru        mem->idx=newIndex;
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uprv_memset(p, 0, n*mem->size);
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return p;
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
353