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