1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* Copyright (C) 1999-2010, 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 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h> 22db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru#include <sys/stat.h> 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef U_WINDOWS 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# define VC_EXTRALEAN 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# define WIN32_LEAN_AND_MEAN 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# define NOUSER 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# define NOSERVICE 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# define NOIME 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# define NOMCX 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# include <windows.h> 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# include <direct.h> 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# include <sys/stat.h> 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru# include <sys/types.h> 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 3827f654740f2a26ad62a5c155af9199af9e69b889claireho 3927f654740f2a26ad62a5c155af9199af9e69b889claireho/* In MinGW environment, io.h needs to be included for _mkdir() */ 4027f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef __MINGW32__ 4127f654740f2a26ad62a5c155af9199af9e69b889claireho#include <io.h> 4227f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 4327f654740f2a26ad62a5c155af9199af9e69b889claireho 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <errno.h> 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/errorcode.h" 4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/putil.h" 4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cmemory.h" 4950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cstring.h" 5050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "toolutil.h" 5150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/ucal.h" 5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 5350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_BEGIN 5450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 5550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoIcuToolErrorCode::~IcuToolErrorCode() { 5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Safe because our handleFailure() does not throw exceptions. 5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(isFailure()) { handleFailure(); } 5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 6050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid IcuToolErrorCode::handleFailure() const { 6150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fprintf(stderr, "error at %s: %s\n", location, errorName()); 6250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho exit(errorCode); 6350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 6550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_END 6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 677d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Querustatic int32_t currentYear = -1; 687d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru 697d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 getCurrentYear() { 707d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 717d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru UErrorCode status=U_ZERO_ERROR; 727d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru UCalendar *cal = NULL; 737d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru 747d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru if(currentYear == -1) { 757d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru cal = ucal_open(NULL, -1, NULL, UCAL_TRADITIONAL, &status); 767d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru ucal_setMillis(cal, ucal_getNow(), &status); 777d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru currentYear = ucal_get(cal, UCAL_YEAR, &status); 787d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru ucal_close(cal); 797d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru } 807d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru#else 8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* No formatting- no way to set the current year. */ 827d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru#endif 8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return currentYear; 847d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru} 857d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru 867d74eed506175eab63e83279a1f3201e1ce33e35Jean-Baptiste Queru 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char * U_EXPORT2 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerugetLongPathname(const char *pathname) { 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef U_WINDOWS 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* anticipate problems with "short" pathnames */ 913d5f03535b3762504420499f55a5810325e5b539Jean-Baptiste Queru static WIN32_FIND_DATAA info; 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru HANDLE file=FindFirstFileA(pathname, &info); 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(file!=INVALID_HANDLE_VALUE) { 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(info.cAlternateFileName[0]!=0) { 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* this file has a short name, get and use the long one */ 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *basename=findBasename(pathname); 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(basename!=pathname) { 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* prepend the long filename with the original path */ 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memmove(info.cFileName+(basename-pathname), info.cFileName, uprv_strlen(info.cFileName)+1); 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(info.cFileName, pathname, basename-pathname); 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pathname=info.cFileName; 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FindClose(file); 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return pathname; 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const char * U_EXPORT2 11150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehofindDirname(const char *path, char *buffer, int32_t bufLen, UErrorCode* status) { 11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_FAILURE(*status)) return NULL; 11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *resultPtr = NULL; 11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t resultLen = 0; 11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *basename=uprv_strrchr(path, U_FILE_SEP_CHAR); 11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if U_FILE_ALT_SEP_CHAR!=U_FILE_SEP_CHAR 11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *basenameAlt=uprv_strrchr(path, U_FILE_ALT_SEP_CHAR); 11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(basenameAlt && (!basename || basename<basenameAlt)) { 12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho basename = basenameAlt; 12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!basename) { 12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* no basename - return '.'. */ 12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resultPtr = "."; 12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resultLen = 1; 12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 12850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resultPtr = path; 12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resultLen = basename - path; 13050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(resultLen<1) { 13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resultLen = 1; /* '/' or '/a' -> '/' */ 13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 13350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if((resultLen+1) <= bufLen) { 13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_strncpy(buffer, resultPtr, resultLen); 13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho buffer[resultLen]=0; 13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return buffer; 13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *status = U_BUFFER_OVERFLOW_ERROR; 14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return NULL; 14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 14550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI const char * U_EXPORT2 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerufindBasename(const char *filename) { 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *basename=uprv_strrchr(filename, U_FILE_SEP_CHAR); 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if U_FILE_ALT_SEP_CHAR!=U_FILE_SEP_CHAR 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(basename==NULL) { 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Use lenient matching on Windows, which can accept either \ or / 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This is useful for environments like Win32+CygWin which have both. 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru basename=uprv_strrchr(filename, U_FILE_ALT_SEP_CHAR); 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(basename!=NULL) { 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return basename+1; 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return filename; 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_mkdir(const char *pathname, UErrorCode *status) { 167db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int retVal = 0; 16927f654740f2a26ad62a5c155af9199af9e69b889claireho#if defined(U_WINDOWS) || defined(__MINGW32__) 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru retVal = _mkdir(pathname); 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru retVal = mkdir(pathname, S_IRWXU | (S_IROTH | S_IXOTH) | (S_IROTH | S_IXOTH)); 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (retVal && errno != EEXIST) { 175db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru#if defined(U_CYGWIN) 176db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru /*if using Cygwin and the mkdir says it failed...check if the directory already exists..*/ 177db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru /* if it does...don't give the error, if it does not...give the error - Brian Rower - 6/25/08 */ 178db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru struct stat st; 179db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru 180db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru if(stat(pathname,&st) != 0) 181db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru { 182db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru *status = U_FILE_ACCESS_ERROR; 183db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru } 184db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru#else 185db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru *status = U_FILE_ACCESS_ERROR; 186db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru#endif 187db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru } 188db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru} 189db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru 190db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru/*U_CAPI UDate U_EXPORT2 191db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queruuprv_getModificationDate(const char *pathname, UErrorCode *status) 192db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru{ 193db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru if(U_FAILURE(*status)) { 194db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru return; 195db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru } 196db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru // TODO: handle case where stat is not available 197db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru struct stat st; 198db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru 199db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru if(stat(pathname,&st) != 0) 200db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru { 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *status = U_FILE_ACCESS_ERROR; 202db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru } else { 203db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru return st.st_mtime; 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 206db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru*/ 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* tool memory helper ------------------------------------------------------- */ 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustruct UToolMemory { 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char name[64]; 212db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru int32_t capacity, maxCapacity, size, idx; 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void *array; 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UAlignedMemory staticArray[1]; 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UToolMemory * U_EXPORT2 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_open(const char *name, int32_t initialCapacity, int32_t maxCapacity, int32_t size) { 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UToolMemory *mem; 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(maxCapacity<initialCapacity) { 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru maxCapacity=initialCapacity; 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mem=(UToolMemory *)uprv_malloc(sizeof(UToolMemory)+initialCapacity*size); 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(mem==NULL) { 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "error: %s - out of memory\n", name); 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru exit(U_MEMORY_ALLOCATION_ERROR); 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mem->array=mem->staticArray; 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_strcpy(mem->name, name); 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mem->capacity=initialCapacity; 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mem->maxCapacity=maxCapacity; 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mem->size=size; 236db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru mem->idx=0; 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return mem; 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_close(UToolMemory *mem) { 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(mem!=NULL) { 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(mem->array!=mem->staticArray) { 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(mem->array); 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(mem); 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void * U_EXPORT2 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_getStart(UToolMemory *mem) { 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (char *)mem->array; 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_countItems(UToolMemory *mem) { 258db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru return mem->idx; 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_hasCapacity(UToolMemory *mem, int32_t capacity) { 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(mem->capacity<capacity) { 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t newCapacity; 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(mem->maxCapacity<capacity) { 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "error: %s - trying to use more than maxCapacity=%ld units\n", 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mem->name, (long)mem->maxCapacity); 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru exit(U_MEMORY_ALLOCATION_ERROR); 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* try to allocate a larger array */ 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(capacity>=2*mem->capacity) { 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru newCapacity=capacity; 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(mem->capacity<=mem->maxCapacity/3) { 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru newCapacity=2*mem->capacity; 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru newCapacity=mem->maxCapacity; 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(mem->array==mem->staticArray) { 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mem->array=uprv_malloc(newCapacity*mem->size); 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(mem->array!=NULL) { 285db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru uprv_memcpy(mem->array, mem->staticArray, mem->idx*mem->size); 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mem->array=uprv_realloc(mem->array, newCapacity*mem->size); 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(mem->array==NULL) { 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "error: %s - out of memory\n", mem->name); 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru exit(U_MEMORY_ALLOCATION_ERROR); 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 29550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho mem->capacity=newCapacity; 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void * U_EXPORT2 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_alloc(UToolMemory *mem) { 30350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *p=NULL; 30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t oldIndex=mem->idx; 30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t newIndex=oldIndex+1; 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(utm_hasCapacity(mem, newIndex)) { 30750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=(char *)mem->array+oldIndex*mem->size; 308db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru mem->idx=newIndex; 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(p, 0, mem->size); 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return p; 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void * U_EXPORT2 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruutm_allocN(UToolMemory *mem, int32_t n) { 31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *p=NULL; 31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t oldIndex=mem->idx; 31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t newIndex=oldIndex+n; 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(utm_hasCapacity(mem, newIndex)) { 32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=(char *)mem->array+oldIndex*mem->size; 321db20b09c124abfd4c87566c93fe35276b1382b61Jean-Baptiste Queru mem->idx=newIndex; 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(p, 0, n*mem->size); 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return p; 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 326