• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *******************************************************************************
3 *
4 *   Copyright (C) 1999-2007, 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 
26 #ifdef U_WINDOWS
27 #   define VC_EXTRALEAN
28 #   define WIN32_LEAN_AND_MEAN
29 #   define NOUSER
30 #   define NOSERVICE
31 #   define NOIME
32 #   define NOMCX
33 #   include <windows.h>
34 #   include <direct.h>
35 #else
36 #   include <sys/stat.h>
37 #   include <sys/types.h>
38 #endif
39 #include <errno.h>
40 
41 U_CAPI const char * U_EXPORT2
getLongPathname(const char * pathname)42 getLongPathname(const char *pathname) {
43 #ifdef U_WINDOWS
44     /* anticipate problems with "short" pathnames */
45     static WIN32_FIND_DATA info;
46     HANDLE file=FindFirstFileA(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 
64 U_CAPI const char * U_EXPORT2
findBasename(const char * filename)65 findBasename(const char *filename) {
66     const char *basename=uprv_strrchr(filename, U_FILE_SEP_CHAR);
67 
68 #if U_FILE_ALT_SEP_CHAR!=U_FILE_SEP_CHAR
69     if(basename==NULL) {
70         /* Use lenient matching on Windows, which can accept either \ or /
71            This is useful for environments like Win32+CygWin which have both.
72         */
73         basename=uprv_strrchr(filename, U_FILE_ALT_SEP_CHAR);
74     }
75 #endif
76 
77     if(basename!=NULL) {
78         return basename+1;
79     } else {
80         return filename;
81     }
82 }
83 
84 U_CAPI void U_EXPORT2
uprv_mkdir(const char * pathname,UErrorCode * status)85 uprv_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 
97 /* tool memory helper ------------------------------------------------------- */
98 
99 struct UToolMemory {
100     char name[64];
101     int32_t capacity, maxCapacity, size, index;
102     void *array;
103     UAlignedMemory staticArray[1];
104 };
105 
106 U_CAPI UToolMemory * U_EXPORT2
utm_open(const char * name,int32_t initialCapacity,int32_t maxCapacity,int32_t size)107 utm_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 
129 U_CAPI void U_EXPORT2
utm_close(UToolMemory * mem)130 utm_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 
140 U_CAPI void * U_EXPORT2
utm_getStart(UToolMemory * mem)141 utm_getStart(UToolMemory *mem) {
142     return (char *)mem->array;
143 }
144 
145 U_CAPI int32_t U_EXPORT2
utm_countItems(UToolMemory * mem)146 utm_countItems(UToolMemory *mem) {
147     return mem->index;
148 }
149 
150 
151 static UBool
utm_hasCapacity(UToolMemory * mem,int32_t capacity)152 utm_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 
189 U_CAPI void * U_EXPORT2
utm_alloc(UToolMemory * mem)190 utm_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 
200 U_CAPI void * U_EXPORT2
utm_allocN(UToolMemory * mem,int32_t n)201 utm_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 }
210