]> git.saurik.com Git - apple/icu.git/blame - icuSources/tools/toolutil/toolutil.c
ICU-400.42.tar.gz
[apple/icu.git] / icuSources / tools / toolutil / toolutil.c
CommitLineData
b75a7d8f
A
1/*
2*******************************************************************************
3*
46f4442e 4* Copyright (C) 1999-2008, International Business Machines
b75a7d8f
A
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* This file contains utility functions for ICU tools like genccode.
17*/
18
73c04bcf
A
19#include <stdio.h>
20#include "unicode/utypes.h"
21#include "unicode/putil.h"
22#include "cmemory.h"
23#include "cstring.h"
24#include "toolutil.h"
46f4442e 25#include "unicode/ucal.h"
73c04bcf
A
26
27#ifdef U_WINDOWS
b75a7d8f
A
28# define VC_EXTRALEAN
29# define WIN32_LEAN_AND_MEAN
b75a7d8f
A
30# define NOUSER
31# define NOSERVICE
32# define NOIME
33# define NOMCX
34# include <windows.h>
73c04bcf
A
35# include <direct.h>
36#else
37# include <sys/stat.h>
38# include <sys/types.h>
b75a7d8f 39#endif
73c04bcf 40#include <errno.h>
b75a7d8f 41
46f4442e
A
42static int32_t currentYear = -1;
43
44U_CAPI int32_t U_EXPORT2 getCurrentYear() {
45#if !UCONFIG_NO_FORMATTING
46 UErrorCode status=U_ZERO_ERROR;
47 UCalendar *cal = NULL;
48
49 if(currentYear == -1) {
50 cal = ucal_open(NULL, -1, NULL, UCAL_TRADITIONAL, &status);
51 ucal_setMillis(cal, ucal_getNow(), &status);
52 currentYear = ucal_get(cal, UCAL_YEAR, &status);
53 ucal_close(cal);
54 }
55 return currentYear;
56#else
57 return 2008;
58#endif
59}
60
61
b75a7d8f
A
62U_CAPI const char * U_EXPORT2
63getLongPathname(const char *pathname) {
73c04bcf 64#ifdef U_WINDOWS
b75a7d8f
A
65 /* anticipate problems with "short" pathnames */
66 static WIN32_FIND_DATA info;
46f4442e 67 HANDLE file=FindFirstFileA(pathname, &info);
b75a7d8f
A
68 if(file!=INVALID_HANDLE_VALUE) {
69 if(info.cAlternateFileName[0]!=0) {
70 /* this file has a short name, get and use the long one */
71 const char *basename=findBasename(pathname);
72 if(basename!=pathname) {
73 /* prepend the long filename with the original path */
74 uprv_memmove(info.cFileName+(basename-pathname), info.cFileName, uprv_strlen(info.cFileName)+1);
75 uprv_memcpy(info.cFileName, pathname, basename-pathname);
76 }
77 pathname=info.cFileName;
78 }
79 FindClose(file);
80 }
81#endif
82 return pathname;
83}
84
85U_CAPI const char * U_EXPORT2
86findBasename(const char *filename) {
87 const char *basename=uprv_strrchr(filename, U_FILE_SEP_CHAR);
374ca955
A
88
89#if U_FILE_ALT_SEP_CHAR!=U_FILE_SEP_CHAR
90 if(basename==NULL) {
b75a7d8f 91 /* Use lenient matching on Windows, which can accept either \ or /
374ca955 92 This is useful for environments like Win32+CygWin which have both.
b75a7d8f 93 */
374ca955
A
94 basename=uprv_strrchr(filename, U_FILE_ALT_SEP_CHAR);
95 }
b75a7d8f 96#endif
374ca955
A
97
98 if(basename!=NULL) {
99 return basename+1;
100 } else {
b75a7d8f
A
101 return filename;
102 }
103}
374ca955 104
73c04bcf
A
105U_CAPI void U_EXPORT2
106uprv_mkdir(const char *pathname, UErrorCode *status) {
107 int retVal = 0;
108#if defined(U_WINDOWS)
109 retVal = _mkdir(pathname);
110#else
111 retVal = mkdir(pathname, S_IRWXU | (S_IROTH | S_IXOTH) | (S_IROTH | S_IXOTH));
112#endif
113 if (retVal && errno != EEXIST) {
114 *status = U_FILE_ACCESS_ERROR;
115 }
116}
117
374ca955
A
118/* tool memory helper ------------------------------------------------------- */
119
120struct UToolMemory {
121 char name[64];
122 int32_t capacity, maxCapacity, size, index;
123 void *array;
124 UAlignedMemory staticArray[1];
125};
126
127U_CAPI UToolMemory * U_EXPORT2
128utm_open(const char *name, int32_t initialCapacity, int32_t maxCapacity, int32_t size) {
129 UToolMemory *mem;
130
131 if(maxCapacity<initialCapacity) {
132 maxCapacity=initialCapacity;
133 }
134
135 mem=(UToolMemory *)uprv_malloc(sizeof(UToolMemory)+initialCapacity*size);
136 if(mem==NULL) {
137 fprintf(stderr, "error: %s - out of memory\n", name);
138 exit(U_MEMORY_ALLOCATION_ERROR);
139 }
140 mem->array=mem->staticArray;
141
142 uprv_strcpy(mem->name, name);
143 mem->capacity=initialCapacity;
144 mem->maxCapacity=maxCapacity;
145 mem->size=size;
146 mem->index=0;
147 return mem;
148}
149
150U_CAPI void U_EXPORT2
151utm_close(UToolMemory *mem) {
152 if(mem!=NULL) {
153 if(mem->array!=mem->staticArray) {
154 uprv_free(mem->array);
155 }
156 uprv_free(mem);
157 }
158}
159
160
161U_CAPI void * U_EXPORT2
162utm_getStart(UToolMemory *mem) {
163 return (char *)mem->array;
164}
165
166U_CAPI int32_t U_EXPORT2
167utm_countItems(UToolMemory *mem) {
168 return mem->index;
169}
170
171
172static UBool
173utm_hasCapacity(UToolMemory *mem, int32_t capacity) {
174 if(mem->capacity<capacity) {
175 int32_t newCapacity;
176
177 if(mem->maxCapacity<capacity) {
178 fprintf(stderr, "error: %s - trying to use more than maxCapacity=%ld units\n",
179 mem->name, (long)mem->maxCapacity);
180 exit(U_MEMORY_ALLOCATION_ERROR);
181 }
182
183 /* try to allocate a larger array */
184 if(capacity>=2*mem->capacity) {
185 newCapacity=capacity;
186 } else if(mem->capacity<=mem->maxCapacity/3) {
187 newCapacity=2*mem->capacity;
188 } else {
189 newCapacity=mem->maxCapacity;
190 }
191
192 if(mem->array==mem->staticArray) {
193 mem->array=uprv_malloc(newCapacity*mem->size);
194 if(mem->array!=NULL) {
195 uprv_memcpy(mem->array, mem->staticArray, mem->index*mem->size);
196 }
197 } else {
198 mem->array=uprv_realloc(mem->array, newCapacity*mem->size);
199 }
200
201 if(mem->array==NULL) {
202 fprintf(stderr, "error: %s - out of memory\n", mem->name);
203 exit(U_MEMORY_ALLOCATION_ERROR);
204 }
205 }
206
207 return TRUE;
208}
209
210U_CAPI void * U_EXPORT2
211utm_alloc(UToolMemory *mem) {
212 char *p=(char *)mem->array+mem->index*mem->size;
213 int32_t newIndex=mem->index+1;
214 if(utm_hasCapacity(mem, newIndex)) {
215 mem->index=newIndex;
216 uprv_memset(p, 0, mem->size);
217 }
218 return p;
219}
220
221U_CAPI void * U_EXPORT2
222utm_allocN(UToolMemory *mem, int32_t n) {
223 char *p=(char *)mem->array+mem->index*mem->size;
224 int32_t newIndex=mem->index+n;
225 if(utm_hasCapacity(mem, newIndex)) {
226 mem->index=newIndex;
227 uprv_memset(p, 0, n*mem->size);
228 }
229 return p;
230}