]> git.saurik.com Git - apple/icu.git/blob - icuSources/tools/toolutil/toolutil.c
ICU-400.40.tar.gz
[apple/icu.git] / icuSources / tools / toolutil / toolutil.c
1 /*
2 *******************************************************************************
3 *
4 * Copyright (C) 1999-2008, 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 * This file contains utility functions for ICU tools like genccode.
17 */
18
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"
25 #include "unicode/ucal.h"
26
27 #ifdef U_WINDOWS
28 # define VC_EXTRALEAN
29 # define WIN32_LEAN_AND_MEAN
30 # define NOUSER
31 # define NOSERVICE
32 # define NOIME
33 # define NOMCX
34 # include <windows.h>
35 # include <direct.h>
36 #else
37 # include <sys/stat.h>
38 # include <sys/types.h>
39 #endif
40 #include <errno.h>
41
42 static int32_t currentYear = -1;
43
44 U_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
62 U_CAPI const char * U_EXPORT2
63 getLongPathname(const char *pathname) {
64 #ifdef U_WINDOWS
65 /* anticipate problems with "short" pathnames */
66 static WIN32_FIND_DATA info;
67 HANDLE file=FindFirstFileA(pathname, &info);
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
85 U_CAPI const char * U_EXPORT2
86 findBasename(const char *filename) {
87 const char *basename=uprv_strrchr(filename, U_FILE_SEP_CHAR);
88
89 #if U_FILE_ALT_SEP_CHAR!=U_FILE_SEP_CHAR
90 if(basename==NULL) {
91 /* Use lenient matching on Windows, which can accept either \ or /
92 This is useful for environments like Win32+CygWin which have both.
93 */
94 basename=uprv_strrchr(filename, U_FILE_ALT_SEP_CHAR);
95 }
96 #endif
97
98 if(basename!=NULL) {
99 return basename+1;
100 } else {
101 return filename;
102 }
103 }
104
105 U_CAPI void U_EXPORT2
106 uprv_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
118 /* tool memory helper ------------------------------------------------------- */
119
120 struct UToolMemory {
121 char name[64];
122 int32_t capacity, maxCapacity, size, index;
123 void *array;
124 UAlignedMemory staticArray[1];
125 };
126
127 U_CAPI UToolMemory * U_EXPORT2
128 utm_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
150 U_CAPI void U_EXPORT2
151 utm_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
161 U_CAPI void * U_EXPORT2
162 utm_getStart(UToolMemory *mem) {
163 return (char *)mem->array;
164 }
165
166 U_CAPI int32_t U_EXPORT2
167 utm_countItems(UToolMemory *mem) {
168 return mem->index;
169 }
170
171
172 static UBool
173 utm_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
210 U_CAPI void * U_EXPORT2
211 utm_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
221 U_CAPI void * U_EXPORT2
222 utm_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 }