]> git.saurik.com Git - apple/icu.git/blame - icuSources/tools/toolutil/toolutil.c
ICU-6.2.14.tar.gz
[apple/icu.git] / icuSources / tools / toolutil / toolutil.c
CommitLineData
b75a7d8f
A
1/*
2*******************************************************************************
3*
374ca955 4* Copyright (C) 1999-2004, 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
19#ifdef WIN32
20# define VC_EXTRALEAN
21# define WIN32_LEAN_AND_MEAN
b75a7d8f
A
22# define NOUSER
23# define NOSERVICE
24# define NOIME
25# define NOMCX
26# include <windows.h>
27#endif
374ca955 28#include <stdio.h>
b75a7d8f
A
29#include "unicode/utypes.h"
30#include "unicode/putil.h"
31#include "cmemory.h"
32#include "cstring.h"
33#include "toolutil.h"
34
35U_CAPI const char * U_EXPORT2
36getLongPathname(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
58U_CAPI const char * U_EXPORT2
59findBasename(const char *filename) {
60 const char *basename=uprv_strrchr(filename, U_FILE_SEP_CHAR);
374ca955
A
61
62#if U_FILE_ALT_SEP_CHAR!=U_FILE_SEP_CHAR
63 if(basename==NULL) {
b75a7d8f 64 /* Use lenient matching on Windows, which can accept either \ or /
374ca955 65 This is useful for environments like Win32+CygWin which have both.
b75a7d8f 66 */
374ca955
A
67 basename=uprv_strrchr(filename, U_FILE_ALT_SEP_CHAR);
68 }
b75a7d8f 69#endif
374ca955
A
70
71 if(basename!=NULL) {
72 return basename+1;
73 } else {
b75a7d8f
A
74 return filename;
75 }
76}
374ca955
A
77
78/* tool memory helper ------------------------------------------------------- */
79
80struct UToolMemory {
81 char name[64];
82 int32_t capacity, maxCapacity, size, index;
83 void *array;
84 UAlignedMemory staticArray[1];
85};
86
87U_CAPI UToolMemory * U_EXPORT2
88utm_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
110U_CAPI void U_EXPORT2
111utm_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
121U_CAPI void * U_EXPORT2
122utm_getStart(UToolMemory *mem) {
123 return (char *)mem->array;
124}
125
126U_CAPI int32_t U_EXPORT2
127utm_countItems(UToolMemory *mem) {
128 return mem->index;
129}
130
131
132static UBool
133utm_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
170U_CAPI void * U_EXPORT2
171utm_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
181U_CAPI void * U_EXPORT2
182utm_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}