]> git.saurik.com Git - apple/icu.git/blob - icuSources/tools/toolutil/toolutil.c
ICU-6.2.14.tar.gz
[apple/icu.git] / icuSources / tools / toolutil / toolutil.c
1 /*
2 *******************************************************************************
3 *
4 * Copyright (C) 1999-2004, 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 #ifdef WIN32
20 # define VC_EXTRALEAN
21 # define WIN32_LEAN_AND_MEAN
22 # define NOUSER
23 # define NOSERVICE
24 # define NOIME
25 # define NOMCX
26 # include <windows.h>
27 #endif
28 #include <stdio.h>
29 #include "unicode/utypes.h"
30 #include "unicode/putil.h"
31 #include "cmemory.h"
32 #include "cstring.h"
33 #include "toolutil.h"
34
35 U_CAPI const char * U_EXPORT2
36 getLongPathname(const char *pathname) {
37 #ifdef WIN32
38 /* anticipate problems with "short" pathnames */
39 static WIN32_FIND_DATA info;
40 HANDLE file=FindFirstFile(pathname, &info);
41 if(file!=INVALID_HANDLE_VALUE) {
42 if(info.cAlternateFileName[0]!=0) {
43 /* this file has a short name, get and use the long one */
44 const char *basename=findBasename(pathname);
45 if(basename!=pathname) {
46 /* prepend the long filename with the original path */
47 uprv_memmove(info.cFileName+(basename-pathname), info.cFileName, uprv_strlen(info.cFileName)+1);
48 uprv_memcpy(info.cFileName, pathname, basename-pathname);
49 }
50 pathname=info.cFileName;
51 }
52 FindClose(file);
53 }
54 #endif
55 return pathname;
56 }
57
58 U_CAPI const char * U_EXPORT2
59 findBasename(const char *filename) {
60 const char *basename=uprv_strrchr(filename, U_FILE_SEP_CHAR);
61
62 #if U_FILE_ALT_SEP_CHAR!=U_FILE_SEP_CHAR
63 if(basename==NULL) {
64 /* Use lenient matching on Windows, which can accept either \ or /
65 This is useful for environments like Win32+CygWin which have both.
66 */
67 basename=uprv_strrchr(filename, U_FILE_ALT_SEP_CHAR);
68 }
69 #endif
70
71 if(basename!=NULL) {
72 return basename+1;
73 } else {
74 return filename;
75 }
76 }
77
78 /* tool memory helper ------------------------------------------------------- */
79
80 struct UToolMemory {
81 char name[64];
82 int32_t capacity, maxCapacity, size, index;
83 void *array;
84 UAlignedMemory staticArray[1];
85 };
86
87 U_CAPI UToolMemory * U_EXPORT2
88 utm_open(const char *name, int32_t initialCapacity, int32_t maxCapacity, int32_t size) {
89 UToolMemory *mem;
90
91 if(maxCapacity<initialCapacity) {
92 maxCapacity=initialCapacity;
93 }
94
95 mem=(UToolMemory *)uprv_malloc(sizeof(UToolMemory)+initialCapacity*size);
96 if(mem==NULL) {
97 fprintf(stderr, "error: %s - out of memory\n", name);
98 exit(U_MEMORY_ALLOCATION_ERROR);
99 }
100 mem->array=mem->staticArray;
101
102 uprv_strcpy(mem->name, name);
103 mem->capacity=initialCapacity;
104 mem->maxCapacity=maxCapacity;
105 mem->size=size;
106 mem->index=0;
107 return mem;
108 }
109
110 U_CAPI void U_EXPORT2
111 utm_close(UToolMemory *mem) {
112 if(mem!=NULL) {
113 if(mem->array!=mem->staticArray) {
114 uprv_free(mem->array);
115 }
116 uprv_free(mem);
117 }
118 }
119
120
121 U_CAPI void * U_EXPORT2
122 utm_getStart(UToolMemory *mem) {
123 return (char *)mem->array;
124 }
125
126 U_CAPI int32_t U_EXPORT2
127 utm_countItems(UToolMemory *mem) {
128 return mem->index;
129 }
130
131
132 static UBool
133 utm_hasCapacity(UToolMemory *mem, int32_t capacity) {
134 if(mem->capacity<capacity) {
135 int32_t newCapacity;
136
137 if(mem->maxCapacity<capacity) {
138 fprintf(stderr, "error: %s - trying to use more than maxCapacity=%ld units\n",
139 mem->name, (long)mem->maxCapacity);
140 exit(U_MEMORY_ALLOCATION_ERROR);
141 }
142
143 /* try to allocate a larger array */
144 if(capacity>=2*mem->capacity) {
145 newCapacity=capacity;
146 } else if(mem->capacity<=mem->maxCapacity/3) {
147 newCapacity=2*mem->capacity;
148 } else {
149 newCapacity=mem->maxCapacity;
150 }
151
152 if(mem->array==mem->staticArray) {
153 mem->array=uprv_malloc(newCapacity*mem->size);
154 if(mem->array!=NULL) {
155 uprv_memcpy(mem->array, mem->staticArray, mem->index*mem->size);
156 }
157 } else {
158 mem->array=uprv_realloc(mem->array, newCapacity*mem->size);
159 }
160
161 if(mem->array==NULL) {
162 fprintf(stderr, "error: %s - out of memory\n", mem->name);
163 exit(U_MEMORY_ALLOCATION_ERROR);
164 }
165 }
166
167 return TRUE;
168 }
169
170 U_CAPI void * U_EXPORT2
171 utm_alloc(UToolMemory *mem) {
172 char *p=(char *)mem->array+mem->index*mem->size;
173 int32_t newIndex=mem->index+1;
174 if(utm_hasCapacity(mem, newIndex)) {
175 mem->index=newIndex;
176 uprv_memset(p, 0, mem->size);
177 }
178 return p;
179 }
180
181 U_CAPI void * U_EXPORT2
182 utm_allocN(UToolMemory *mem, int32_t n) {
183 char *p=(char *)mem->array+mem->index*mem->size;
184 int32_t newIndex=mem->index+n;
185 if(utm_hasCapacity(mem, newIndex)) {
186 mem->index=newIndex;
187 uprv_memset(p, 0, n*mem->size);
188 }
189 return p;
190 }