1*27162e4eSAndroid Build Coastguard Worker /*
2*27162e4eSAndroid Build Coastguard Worker util.h - utility functions
3*27162e4eSAndroid Build Coastguard Worker Copyright (C) 2016-2023, Przemyslaw Skibinski, Yann Collet
4*27162e4eSAndroid Build Coastguard Worker
5*27162e4eSAndroid Build Coastguard Worker This program is free software; you can redistribute it and/or modify
6*27162e4eSAndroid Build Coastguard Worker it under the terms of the GNU General Public License as published by
7*27162e4eSAndroid Build Coastguard Worker the Free Software Foundation; either version 2 of the License, or
8*27162e4eSAndroid Build Coastguard Worker (at your option) any later version.
9*27162e4eSAndroid Build Coastguard Worker
10*27162e4eSAndroid Build Coastguard Worker This program is distributed in the hope that it will be useful,
11*27162e4eSAndroid Build Coastguard Worker but WITHOUT ANY WARRANTY; without even the implied warranty of
12*27162e4eSAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13*27162e4eSAndroid Build Coastguard Worker GNU General Public License for more details.
14*27162e4eSAndroid Build Coastguard Worker
15*27162e4eSAndroid Build Coastguard Worker You should have received a copy of the GNU General Public License along
16*27162e4eSAndroid Build Coastguard Worker with this program; if not, write to the Free Software Foundation, Inc.,
17*27162e4eSAndroid Build Coastguard Worker 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18*27162e4eSAndroid Build Coastguard Worker */
19*27162e4eSAndroid Build Coastguard Worker
20*27162e4eSAndroid Build Coastguard Worker #ifndef UTIL_H_MODULE
21*27162e4eSAndroid Build Coastguard Worker #define UTIL_H_MODULE
22*27162e4eSAndroid Build Coastguard Worker
23*27162e4eSAndroid Build Coastguard Worker #if defined (__cplusplus)
24*27162e4eSAndroid Build Coastguard Worker extern "C" {
25*27162e4eSAndroid Build Coastguard Worker #endif
26*27162e4eSAndroid Build Coastguard Worker
27*27162e4eSAndroid Build Coastguard Worker
28*27162e4eSAndroid Build Coastguard Worker
29*27162e4eSAndroid Build Coastguard Worker /*-****************************************
30*27162e4eSAndroid Build Coastguard Worker * Dependencies
31*27162e4eSAndroid Build Coastguard Worker ******************************************/
32*27162e4eSAndroid Build Coastguard Worker #include "platform.h" /* PLATFORM_POSIX_VERSION */
33*27162e4eSAndroid Build Coastguard Worker #include <stddef.h> /* size_t, ptrdiff_t */
34*27162e4eSAndroid Build Coastguard Worker #include <stdlib.h> /* malloc */
35*27162e4eSAndroid Build Coastguard Worker #include <string.h> /* strlen, strncpy */
36*27162e4eSAndroid Build Coastguard Worker #include <stdio.h> /* fprintf, fileno */
37*27162e4eSAndroid Build Coastguard Worker #include <assert.h>
38*27162e4eSAndroid Build Coastguard Worker #include <sys/types.h> /* stat, utime */
39*27162e4eSAndroid Build Coastguard Worker #include <sys/stat.h> /* stat */
40*27162e4eSAndroid Build Coastguard Worker #if defined(_WIN32)
41*27162e4eSAndroid Build Coastguard Worker # include <sys/utime.h> /* utime */
42*27162e4eSAndroid Build Coastguard Worker # include <io.h> /* _chmod */
43*27162e4eSAndroid Build Coastguard Worker #else
44*27162e4eSAndroid Build Coastguard Worker # include <unistd.h> /* chown, stat */
45*27162e4eSAndroid Build Coastguard Worker # if PLATFORM_POSIX_VERSION < 200809L
46*27162e4eSAndroid Build Coastguard Worker # include <utime.h> /* utime */
47*27162e4eSAndroid Build Coastguard Worker # else
48*27162e4eSAndroid Build Coastguard Worker # include <fcntl.h> /* AT_FDCWD */
49*27162e4eSAndroid Build Coastguard Worker # include <sys/stat.h> /* for utimensat */
50*27162e4eSAndroid Build Coastguard Worker # endif
51*27162e4eSAndroid Build Coastguard Worker #endif
52*27162e4eSAndroid Build Coastguard Worker #include <time.h> /* time */
53*27162e4eSAndroid Build Coastguard Worker #include <limits.h> /* INT_MAX */
54*27162e4eSAndroid Build Coastguard Worker #include <errno.h>
55*27162e4eSAndroid Build Coastguard Worker
56*27162e4eSAndroid Build Coastguard Worker
57*27162e4eSAndroid Build Coastguard Worker
58*27162e4eSAndroid Build Coastguard Worker /*-**************************************************************
59*27162e4eSAndroid Build Coastguard Worker * Basic Types
60*27162e4eSAndroid Build Coastguard Worker *****************************************************************/
61*27162e4eSAndroid Build Coastguard Worker #if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
62*27162e4eSAndroid Build Coastguard Worker # include <stdint.h>
63*27162e4eSAndroid Build Coastguard Worker typedef uint8_t BYTE;
64*27162e4eSAndroid Build Coastguard Worker typedef uint16_t U16;
65*27162e4eSAndroid Build Coastguard Worker typedef int16_t S16;
66*27162e4eSAndroid Build Coastguard Worker typedef uint32_t U32;
67*27162e4eSAndroid Build Coastguard Worker typedef int32_t S32;
68*27162e4eSAndroid Build Coastguard Worker typedef uint64_t U64;
69*27162e4eSAndroid Build Coastguard Worker typedef int64_t S64;
70*27162e4eSAndroid Build Coastguard Worker #else
71*27162e4eSAndroid Build Coastguard Worker typedef unsigned char BYTE;
72*27162e4eSAndroid Build Coastguard Worker typedef unsigned short U16;
73*27162e4eSAndroid Build Coastguard Worker typedef signed short S16;
74*27162e4eSAndroid Build Coastguard Worker typedef unsigned int U32;
75*27162e4eSAndroid Build Coastguard Worker typedef signed int S32;
76*27162e4eSAndroid Build Coastguard Worker typedef unsigned long long U64;
77*27162e4eSAndroid Build Coastguard Worker typedef signed long long S64;
78*27162e4eSAndroid Build Coastguard Worker #endif
79*27162e4eSAndroid Build Coastguard Worker
80*27162e4eSAndroid Build Coastguard Worker
81*27162e4eSAndroid Build Coastguard Worker /* ************************************************************
82*27162e4eSAndroid Build Coastguard Worker * Avoid fseek()'s 2GiB barrier with MSVC, MacOS, *BSD, MinGW
83*27162e4eSAndroid Build Coastguard Worker ***************************************************************/
84*27162e4eSAndroid Build Coastguard Worker #if defined(_MSC_VER) && (_MSC_VER >= 1400)
85*27162e4eSAndroid Build Coastguard Worker # define UTIL_fseek _fseeki64
86*27162e4eSAndroid Build Coastguard Worker #elif !defined(__64BIT__) && (PLATFORM_POSIX_VERSION >= 200112L) /* No point defining Large file for 64 bit */
87*27162e4eSAndroid Build Coastguard Worker # define UTIL_fseek fseeko
88*27162e4eSAndroid Build Coastguard Worker #elif defined(__MINGW32__) && defined(__MSVCRT__) && !defined(__STRICT_ANSI__) && !defined(__NO_MINGW_LFS)
89*27162e4eSAndroid Build Coastguard Worker # define UTIL_fseek fseeko64
90*27162e4eSAndroid Build Coastguard Worker #else
91*27162e4eSAndroid Build Coastguard Worker # define UTIL_fseek fseek
92*27162e4eSAndroid Build Coastguard Worker #endif
93*27162e4eSAndroid Build Coastguard Worker
94*27162e4eSAndroid Build Coastguard Worker /*-****************************************
95*27162e4eSAndroid Build Coastguard Worker * Local host Core counting
96*27162e4eSAndroid Build Coastguard Worker ******************************************/
97*27162e4eSAndroid Build Coastguard Worker int UTIL_countCores(void);
98*27162e4eSAndroid Build Coastguard Worker
99*27162e4eSAndroid Build Coastguard Worker /*-****************************************
100*27162e4eSAndroid Build Coastguard Worker * Sleep functions: Windows - Posix - others
101*27162e4eSAndroid Build Coastguard Worker ******************************************/
102*27162e4eSAndroid Build Coastguard Worker #if defined(_WIN32)
103*27162e4eSAndroid Build Coastguard Worker # include <windows.h>
104*27162e4eSAndroid Build Coastguard Worker # define SET_REALTIME_PRIORITY SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)
105*27162e4eSAndroid Build Coastguard Worker # define UTIL_sleep(s) Sleep(1000*s)
106*27162e4eSAndroid Build Coastguard Worker # define UTIL_sleepMilli(milli) Sleep(milli)
107*27162e4eSAndroid Build Coastguard Worker #elif PLATFORM_POSIX_VERSION >= 0 /* Unix-like operating system */
108*27162e4eSAndroid Build Coastguard Worker # include <unistd.h>
109*27162e4eSAndroid Build Coastguard Worker # include <sys/resource.h> /* setpriority */
110*27162e4eSAndroid Build Coastguard Worker # include <time.h> /* clock_t, nanosleep, clock, CLOCKS_PER_SEC */
111*27162e4eSAndroid Build Coastguard Worker # if defined(PRIO_PROCESS)
112*27162e4eSAndroid Build Coastguard Worker # define SET_REALTIME_PRIORITY setpriority(PRIO_PROCESS, 0, -20)
113*27162e4eSAndroid Build Coastguard Worker # else
114*27162e4eSAndroid Build Coastguard Worker # define SET_REALTIME_PRIORITY /* disabled */
115*27162e4eSAndroid Build Coastguard Worker # endif
116*27162e4eSAndroid Build Coastguard Worker # define UTIL_sleep(s) sleep(s)
117*27162e4eSAndroid Build Coastguard Worker # if (defined(__linux__) && (PLATFORM_POSIX_VERSION >= 199309L)) || (PLATFORM_POSIX_VERSION >= 200112L) /* nanosleep requires POSIX.1-2001 */
118*27162e4eSAndroid Build Coastguard Worker # define UTIL_sleepMilli(milli) { struct timespec t; t.tv_sec=0; t.tv_nsec=milli*1000000ULL; nanosleep(&t, NULL); }
119*27162e4eSAndroid Build Coastguard Worker # else
120*27162e4eSAndroid Build Coastguard Worker # define UTIL_sleepMilli(milli) /* disabled */
121*27162e4eSAndroid Build Coastguard Worker # endif
122*27162e4eSAndroid Build Coastguard Worker #else
123*27162e4eSAndroid Build Coastguard Worker # define SET_REALTIME_PRIORITY /* disabled */
124*27162e4eSAndroid Build Coastguard Worker # define UTIL_sleep(s) /* disabled */
125*27162e4eSAndroid Build Coastguard Worker # define UTIL_sleepMilli(milli) /* disabled */
126*27162e4eSAndroid Build Coastguard Worker #endif
127*27162e4eSAndroid Build Coastguard Worker
128*27162e4eSAndroid Build Coastguard Worker
129*27162e4eSAndroid Build Coastguard Worker /*-****************************************
130*27162e4eSAndroid Build Coastguard Worker * stat() functions
131*27162e4eSAndroid Build Coastguard Worker ******************************************/
132*27162e4eSAndroid Build Coastguard Worker #if defined(_MSC_VER)
133*27162e4eSAndroid Build Coastguard Worker # define UTIL_TYPE_stat __stat64
134*27162e4eSAndroid Build Coastguard Worker # define UTIL_stat _stat64
135*27162e4eSAndroid Build Coastguard Worker # define UTIL_fstat _fstat64
136*27162e4eSAndroid Build Coastguard Worker # define UTIL_STAT_MODE_ISREG(st_mode) ((st_mode) & S_IFREG)
137*27162e4eSAndroid Build Coastguard Worker #elif defined(__MINGW32__) && defined (__MSVCRT__)
138*27162e4eSAndroid Build Coastguard Worker # define UTIL_TYPE_stat _stati64
139*27162e4eSAndroid Build Coastguard Worker # define UTIL_stat _stati64
140*27162e4eSAndroid Build Coastguard Worker # define UTIL_fstat _fstati64
141*27162e4eSAndroid Build Coastguard Worker # define UTIL_STAT_MODE_ISREG(st_mode) ((st_mode) & S_IFREG)
142*27162e4eSAndroid Build Coastguard Worker #else
143*27162e4eSAndroid Build Coastguard Worker # define UTIL_TYPE_stat stat
144*27162e4eSAndroid Build Coastguard Worker # define UTIL_stat stat
145*27162e4eSAndroid Build Coastguard Worker # define UTIL_fstat fstat
146*27162e4eSAndroid Build Coastguard Worker # define UTIL_STAT_MODE_ISREG(st_mode) (S_ISREG(st_mode))
147*27162e4eSAndroid Build Coastguard Worker #endif
148*27162e4eSAndroid Build Coastguard Worker
149*27162e4eSAndroid Build Coastguard Worker
150*27162e4eSAndroid Build Coastguard Worker /*-****************************************
151*27162e4eSAndroid Build Coastguard Worker * fileno() function
152*27162e4eSAndroid Build Coastguard Worker ******************************************/
153*27162e4eSAndroid Build Coastguard Worker #if defined(_MSC_VER)
154*27162e4eSAndroid Build Coastguard Worker # define UTIL_fileno _fileno
155*27162e4eSAndroid Build Coastguard Worker #else
156*27162e4eSAndroid Build Coastguard Worker # define UTIL_fileno fileno
157*27162e4eSAndroid Build Coastguard Worker #endif
158*27162e4eSAndroid Build Coastguard Worker
159*27162e4eSAndroid Build Coastguard Worker /* *************************************
160*27162e4eSAndroid Build Coastguard Worker * Constants
161*27162e4eSAndroid Build Coastguard Worker ***************************************/
162*27162e4eSAndroid Build Coastguard Worker #define LIST_SIZE_INCREASE (8*1024)
163*27162e4eSAndroid Build Coastguard Worker
164*27162e4eSAndroid Build Coastguard Worker
165*27162e4eSAndroid Build Coastguard Worker /*-****************************************
166*27162e4eSAndroid Build Coastguard Worker * Compiler specifics
167*27162e4eSAndroid Build Coastguard Worker ******************************************/
168*27162e4eSAndroid Build Coastguard Worker #if defined(__INTEL_COMPILER)
169*27162e4eSAndroid Build Coastguard Worker # pragma warning(disable : 177) /* disable: message #177: function was declared but never referenced, useful with UTIL_STATIC */
170*27162e4eSAndroid Build Coastguard Worker #endif
171*27162e4eSAndroid Build Coastguard Worker #if defined(__GNUC__)
172*27162e4eSAndroid Build Coastguard Worker # define UTIL_STATIC static __attribute__((unused))
173*27162e4eSAndroid Build Coastguard Worker #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
174*27162e4eSAndroid Build Coastguard Worker # define UTIL_STATIC static inline
175*27162e4eSAndroid Build Coastguard Worker #elif defined(_MSC_VER)
176*27162e4eSAndroid Build Coastguard Worker # define UTIL_STATIC static __inline
177*27162e4eSAndroid Build Coastguard Worker #else
178*27162e4eSAndroid Build Coastguard Worker # define UTIL_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
179*27162e4eSAndroid Build Coastguard Worker #endif
180*27162e4eSAndroid Build Coastguard Worker
181*27162e4eSAndroid Build Coastguard Worker
182*27162e4eSAndroid Build Coastguard Worker
183*27162e4eSAndroid Build Coastguard Worker /*-****************************************
184*27162e4eSAndroid Build Coastguard Worker * Allocation functions
185*27162e4eSAndroid Build Coastguard Worker ******************************************/
186*27162e4eSAndroid Build Coastguard Worker /*
187*27162e4eSAndroid Build Coastguard Worker * A modified version of realloc().
188*27162e4eSAndroid Build Coastguard Worker * If UTIL_realloc() fails the original block is freed.
189*27162e4eSAndroid Build Coastguard Worker */
UTIL_realloc(void * ptr,size_t size)190*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC void* UTIL_realloc(void* ptr, size_t size)
191*27162e4eSAndroid Build Coastguard Worker {
192*27162e4eSAndroid Build Coastguard Worker void* const newptr = realloc(ptr, size);
193*27162e4eSAndroid Build Coastguard Worker if (newptr) return newptr;
194*27162e4eSAndroid Build Coastguard Worker free(ptr);
195*27162e4eSAndroid Build Coastguard Worker return NULL;
196*27162e4eSAndroid Build Coastguard Worker }
197*27162e4eSAndroid Build Coastguard Worker
198*27162e4eSAndroid Build Coastguard Worker
199*27162e4eSAndroid Build Coastguard Worker /*-****************************************
200*27162e4eSAndroid Build Coastguard Worker * String functions
201*27162e4eSAndroid Build Coastguard Worker ******************************************/
202*27162e4eSAndroid Build Coastguard Worker /* supports a==NULL or b==NULL */
UTIL_sameString(const char * a,const char * b)203*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC int UTIL_sameString(const char* a, const char* b)
204*27162e4eSAndroid Build Coastguard Worker {
205*27162e4eSAndroid Build Coastguard Worker assert(a != NULL || b != NULL); /* unsupported scenario */
206*27162e4eSAndroid Build Coastguard Worker if (a==NULL) return 0;
207*27162e4eSAndroid Build Coastguard Worker if (b==NULL) return 0;
208*27162e4eSAndroid Build Coastguard Worker return !strcmp(a,b);
209*27162e4eSAndroid Build Coastguard Worker }
210*27162e4eSAndroid Build Coastguard Worker
211*27162e4eSAndroid Build Coastguard Worker
212*27162e4eSAndroid Build Coastguard Worker
213*27162e4eSAndroid Build Coastguard Worker /*-****************************************
214*27162e4eSAndroid Build Coastguard Worker * File functions
215*27162e4eSAndroid Build Coastguard Worker ******************************************/
216*27162e4eSAndroid Build Coastguard Worker #if defined(_MSC_VER)
217*27162e4eSAndroid Build Coastguard Worker #define chmod _chmod
218*27162e4eSAndroid Build Coastguard Worker typedef struct __stat64 stat_t;
219*27162e4eSAndroid Build Coastguard Worker #else
220*27162e4eSAndroid Build Coastguard Worker typedef struct stat stat_t;
221*27162e4eSAndroid Build Coastguard Worker #endif
222*27162e4eSAndroid Build Coastguard Worker
223*27162e4eSAndroid Build Coastguard Worker
224*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC int UTIL_isRegFile(const char* infilename);
225*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC int UTIL_isRegFD(int fd);
226*27162e4eSAndroid Build Coastguard Worker
227*27162e4eSAndroid Build Coastguard Worker
UTIL_setFileStat(const char * filename,stat_t * statbuf)228*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC int UTIL_setFileStat(const char *filename, stat_t *statbuf)
229*27162e4eSAndroid Build Coastguard Worker {
230*27162e4eSAndroid Build Coastguard Worker int res = 0;
231*27162e4eSAndroid Build Coastguard Worker
232*27162e4eSAndroid Build Coastguard Worker if (!UTIL_isRegFile(filename))
233*27162e4eSAndroid Build Coastguard Worker return -1;
234*27162e4eSAndroid Build Coastguard Worker
235*27162e4eSAndroid Build Coastguard Worker {
236*27162e4eSAndroid Build Coastguard Worker #if defined(_WIN32) || (PLATFORM_POSIX_VERSION < 200809L)
237*27162e4eSAndroid Build Coastguard Worker struct utimbuf timebuf;
238*27162e4eSAndroid Build Coastguard Worker timebuf.actime = time(NULL);
239*27162e4eSAndroid Build Coastguard Worker timebuf.modtime = statbuf->st_mtime;
240*27162e4eSAndroid Build Coastguard Worker res += utime(filename, &timebuf); /* set access and modification times */
241*27162e4eSAndroid Build Coastguard Worker #else
242*27162e4eSAndroid Build Coastguard Worker struct timespec timebuf[2];
243*27162e4eSAndroid Build Coastguard Worker memset(timebuf, 0, sizeof(timebuf));
244*27162e4eSAndroid Build Coastguard Worker timebuf[0].tv_nsec = UTIME_NOW;
245*27162e4eSAndroid Build Coastguard Worker timebuf[1].tv_sec = statbuf->st_mtime;
246*27162e4eSAndroid Build Coastguard Worker res += utimensat(AT_FDCWD, filename, timebuf, 0); /* set access and modification times */
247*27162e4eSAndroid Build Coastguard Worker #endif
248*27162e4eSAndroid Build Coastguard Worker }
249*27162e4eSAndroid Build Coastguard Worker
250*27162e4eSAndroid Build Coastguard Worker #if !defined(_WIN32)
251*27162e4eSAndroid Build Coastguard Worker res += chown(filename, statbuf->st_uid, statbuf->st_gid); /* Copy ownership */
252*27162e4eSAndroid Build Coastguard Worker #endif
253*27162e4eSAndroid Build Coastguard Worker
254*27162e4eSAndroid Build Coastguard Worker res += chmod(filename, statbuf->st_mode & 07777); /* Copy file permissions */
255*27162e4eSAndroid Build Coastguard Worker
256*27162e4eSAndroid Build Coastguard Worker errno = 0;
257*27162e4eSAndroid Build Coastguard Worker return -res; /* number of errors is returned */
258*27162e4eSAndroid Build Coastguard Worker }
259*27162e4eSAndroid Build Coastguard Worker
260*27162e4eSAndroid Build Coastguard Worker
UTIL_getFDStat(int fd,stat_t * statbuf)261*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC int UTIL_getFDStat(int fd, stat_t *statbuf)
262*27162e4eSAndroid Build Coastguard Worker {
263*27162e4eSAndroid Build Coastguard Worker int r;
264*27162e4eSAndroid Build Coastguard Worker #if defined(_MSC_VER)
265*27162e4eSAndroid Build Coastguard Worker r = _fstat64(fd, statbuf);
266*27162e4eSAndroid Build Coastguard Worker if (r || !(statbuf->st_mode & S_IFREG)) return 0; /* No good... */
267*27162e4eSAndroid Build Coastguard Worker #else
268*27162e4eSAndroid Build Coastguard Worker r = fstat(fd, statbuf);
269*27162e4eSAndroid Build Coastguard Worker if (r || !S_ISREG(statbuf->st_mode)) return 0; /* No good... */
270*27162e4eSAndroid Build Coastguard Worker #endif
271*27162e4eSAndroid Build Coastguard Worker return 1;
272*27162e4eSAndroid Build Coastguard Worker }
273*27162e4eSAndroid Build Coastguard Worker
UTIL_getFileStat(const char * infilename,stat_t * statbuf)274*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC int UTIL_getFileStat(const char* infilename, stat_t *statbuf)
275*27162e4eSAndroid Build Coastguard Worker {
276*27162e4eSAndroid Build Coastguard Worker int r;
277*27162e4eSAndroid Build Coastguard Worker #if defined(_MSC_VER)
278*27162e4eSAndroid Build Coastguard Worker r = _stat64(infilename, statbuf);
279*27162e4eSAndroid Build Coastguard Worker if (r || !(statbuf->st_mode & S_IFREG)) return 0; /* No good... */
280*27162e4eSAndroid Build Coastguard Worker #else
281*27162e4eSAndroid Build Coastguard Worker r = stat(infilename, statbuf);
282*27162e4eSAndroid Build Coastguard Worker if (r || !S_ISREG(statbuf->st_mode)) return 0; /* No good... */
283*27162e4eSAndroid Build Coastguard Worker #endif
284*27162e4eSAndroid Build Coastguard Worker return 1;
285*27162e4eSAndroid Build Coastguard Worker }
286*27162e4eSAndroid Build Coastguard Worker
UTIL_isRegFD(int fd)287*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC int UTIL_isRegFD(int fd)
288*27162e4eSAndroid Build Coastguard Worker {
289*27162e4eSAndroid Build Coastguard Worker stat_t statbuf;
290*27162e4eSAndroid Build Coastguard Worker #ifdef _WIN32
291*27162e4eSAndroid Build Coastguard Worker /* Windows runtime library always open file descriptors 0, 1 and 2 in text mode, therefore we can't use them for binary I/O */
292*27162e4eSAndroid Build Coastguard Worker if(fd < 3) return 0;
293*27162e4eSAndroid Build Coastguard Worker #endif
294*27162e4eSAndroid Build Coastguard Worker return UTIL_getFDStat(fd, &statbuf); /* Only need to know whether it is a regular file */
295*27162e4eSAndroid Build Coastguard Worker }
296*27162e4eSAndroid Build Coastguard Worker
UTIL_isRegFile(const char * infilename)297*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC int UTIL_isRegFile(const char* infilename)
298*27162e4eSAndroid Build Coastguard Worker {
299*27162e4eSAndroid Build Coastguard Worker stat_t statbuf;
300*27162e4eSAndroid Build Coastguard Worker return UTIL_getFileStat(infilename, &statbuf); /* Only need to know whether it is a regular file */
301*27162e4eSAndroid Build Coastguard Worker }
302*27162e4eSAndroid Build Coastguard Worker
UTIL_isDirectory(const char * infilename)303*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC int UTIL_isDirectory(const char* infilename)
304*27162e4eSAndroid Build Coastguard Worker {
305*27162e4eSAndroid Build Coastguard Worker stat_t statbuf;
306*27162e4eSAndroid Build Coastguard Worker int r;
307*27162e4eSAndroid Build Coastguard Worker #if defined(_MSC_VER)
308*27162e4eSAndroid Build Coastguard Worker r = _stat64(infilename, &statbuf);
309*27162e4eSAndroid Build Coastguard Worker if (r) return 0;
310*27162e4eSAndroid Build Coastguard Worker return (statbuf.st_mode & S_IFDIR);
311*27162e4eSAndroid Build Coastguard Worker #else
312*27162e4eSAndroid Build Coastguard Worker r = stat(infilename, &statbuf);
313*27162e4eSAndroid Build Coastguard Worker if (r) return 0;
314*27162e4eSAndroid Build Coastguard Worker return (S_ISDIR(statbuf.st_mode));
315*27162e4eSAndroid Build Coastguard Worker #endif
316*27162e4eSAndroid Build Coastguard Worker }
317*27162e4eSAndroid Build Coastguard Worker
318*27162e4eSAndroid Build Coastguard Worker
UTIL_getOpenFileSize(FILE * file)319*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC U64 UTIL_getOpenFileSize(FILE* file)
320*27162e4eSAndroid Build Coastguard Worker {
321*27162e4eSAndroid Build Coastguard Worker int r;
322*27162e4eSAndroid Build Coastguard Worker int fd;
323*27162e4eSAndroid Build Coastguard Worker struct UTIL_TYPE_stat statbuf;
324*27162e4eSAndroid Build Coastguard Worker
325*27162e4eSAndroid Build Coastguard Worker fd = UTIL_fileno(file);
326*27162e4eSAndroid Build Coastguard Worker if (fd < 0) {
327*27162e4eSAndroid Build Coastguard Worker perror("fileno");
328*27162e4eSAndroid Build Coastguard Worker exit(1);
329*27162e4eSAndroid Build Coastguard Worker }
330*27162e4eSAndroid Build Coastguard Worker r = UTIL_fstat(fd, &statbuf);
331*27162e4eSAndroid Build Coastguard Worker if (r || !UTIL_STAT_MODE_ISREG(statbuf.st_mode)) return 0; /* No good... */
332*27162e4eSAndroid Build Coastguard Worker return (U64)statbuf.st_size;
333*27162e4eSAndroid Build Coastguard Worker }
334*27162e4eSAndroid Build Coastguard Worker
335*27162e4eSAndroid Build Coastguard Worker
UTIL_getFileSize(const char * infilename)336*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC U64 UTIL_getFileSize(const char* infilename)
337*27162e4eSAndroid Build Coastguard Worker {
338*27162e4eSAndroid Build Coastguard Worker int r;
339*27162e4eSAndroid Build Coastguard Worker struct UTIL_TYPE_stat statbuf;
340*27162e4eSAndroid Build Coastguard Worker
341*27162e4eSAndroid Build Coastguard Worker r = UTIL_stat(infilename, &statbuf);
342*27162e4eSAndroid Build Coastguard Worker if (r || !UTIL_STAT_MODE_ISREG(statbuf.st_mode)) return 0; /* No good... */
343*27162e4eSAndroid Build Coastguard Worker return (U64)statbuf.st_size;
344*27162e4eSAndroid Build Coastguard Worker }
345*27162e4eSAndroid Build Coastguard Worker
346*27162e4eSAndroid Build Coastguard Worker
UTIL_getTotalFileSize(const char ** fileNamesTable,unsigned nbFiles)347*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC U64 UTIL_getTotalFileSize(const char** fileNamesTable, unsigned nbFiles)
348*27162e4eSAndroid Build Coastguard Worker {
349*27162e4eSAndroid Build Coastguard Worker U64 total = 0;
350*27162e4eSAndroid Build Coastguard Worker unsigned n;
351*27162e4eSAndroid Build Coastguard Worker for (n=0; n<nbFiles; n++)
352*27162e4eSAndroid Build Coastguard Worker total += UTIL_getFileSize(fileNamesTable[n]);
353*27162e4eSAndroid Build Coastguard Worker return total;
354*27162e4eSAndroid Build Coastguard Worker }
355*27162e4eSAndroid Build Coastguard Worker
356*27162e4eSAndroid Build Coastguard Worker
357*27162e4eSAndroid Build Coastguard Worker #ifdef _WIN32
358*27162e4eSAndroid Build Coastguard Worker # define UTIL_HAS_CREATEFILELIST
359*27162e4eSAndroid Build Coastguard Worker
UTIL_prepareFileList(const char * dirName,char ** bufStart,size_t * pos,char ** bufEnd)360*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC int UTIL_prepareFileList(const char* dirName, char** bufStart, size_t* pos, char** bufEnd)
361*27162e4eSAndroid Build Coastguard Worker {
362*27162e4eSAndroid Build Coastguard Worker char* path;
363*27162e4eSAndroid Build Coastguard Worker size_t dirLength, nbFiles = 0;
364*27162e4eSAndroid Build Coastguard Worker WIN32_FIND_DATAA cFile;
365*27162e4eSAndroid Build Coastguard Worker HANDLE hFile;
366*27162e4eSAndroid Build Coastguard Worker
367*27162e4eSAndroid Build Coastguard Worker dirLength = strlen(dirName);
368*27162e4eSAndroid Build Coastguard Worker path = (char*) malloc(dirLength + 3);
369*27162e4eSAndroid Build Coastguard Worker if (!path) return 0;
370*27162e4eSAndroid Build Coastguard Worker
371*27162e4eSAndroid Build Coastguard Worker memcpy(path, dirName, dirLength);
372*27162e4eSAndroid Build Coastguard Worker path[dirLength] = '\\';
373*27162e4eSAndroid Build Coastguard Worker path[dirLength+1] = '*';
374*27162e4eSAndroid Build Coastguard Worker path[dirLength+2] = 0;
375*27162e4eSAndroid Build Coastguard Worker
376*27162e4eSAndroid Build Coastguard Worker hFile=FindFirstFileA(path, &cFile);
377*27162e4eSAndroid Build Coastguard Worker if (hFile == INVALID_HANDLE_VALUE) {
378*27162e4eSAndroid Build Coastguard Worker fprintf(stderr, "Cannot open directory '%s'\n", dirName);
379*27162e4eSAndroid Build Coastguard Worker return 0;
380*27162e4eSAndroid Build Coastguard Worker }
381*27162e4eSAndroid Build Coastguard Worker free(path);
382*27162e4eSAndroid Build Coastguard Worker
383*27162e4eSAndroid Build Coastguard Worker do {
384*27162e4eSAndroid Build Coastguard Worker size_t pathLength;
385*27162e4eSAndroid Build Coastguard Worker int const fnameLength = (int)strlen(cFile.cFileName);
386*27162e4eSAndroid Build Coastguard Worker path = (char*) malloc(dirLength + fnameLength + 2);
387*27162e4eSAndroid Build Coastguard Worker if (!path) { FindClose(hFile); return 0; }
388*27162e4eSAndroid Build Coastguard Worker memcpy(path, dirName, dirLength);
389*27162e4eSAndroid Build Coastguard Worker path[dirLength] = '\\';
390*27162e4eSAndroid Build Coastguard Worker memcpy(path+dirLength+1, cFile.cFileName, fnameLength);
391*27162e4eSAndroid Build Coastguard Worker pathLength = dirLength+1+fnameLength;
392*27162e4eSAndroid Build Coastguard Worker path[pathLength] = 0;
393*27162e4eSAndroid Build Coastguard Worker if (cFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
394*27162e4eSAndroid Build Coastguard Worker if (strcmp (cFile.cFileName, "..") == 0 ||
395*27162e4eSAndroid Build Coastguard Worker strcmp (cFile.cFileName, ".") == 0) continue;
396*27162e4eSAndroid Build Coastguard Worker
397*27162e4eSAndroid Build Coastguard Worker nbFiles += UTIL_prepareFileList(path, bufStart, pos, bufEnd); /* Recursively call "UTIL_prepareFileList" with the new path. */
398*27162e4eSAndroid Build Coastguard Worker if (*bufStart == NULL) { free(path); FindClose(hFile); return 0; }
399*27162e4eSAndroid Build Coastguard Worker }
400*27162e4eSAndroid Build Coastguard Worker else if ((cFile.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) || (cFile.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) || (cFile.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)) {
401*27162e4eSAndroid Build Coastguard Worker if (*bufStart + *pos + pathLength >= *bufEnd) {
402*27162e4eSAndroid Build Coastguard Worker ptrdiff_t newListSize = (*bufEnd - *bufStart) + LIST_SIZE_INCREASE;
403*27162e4eSAndroid Build Coastguard Worker *bufStart = (char*)UTIL_realloc(*bufStart, newListSize);
404*27162e4eSAndroid Build Coastguard Worker *bufEnd = *bufStart + newListSize;
405*27162e4eSAndroid Build Coastguard Worker if (*bufStart == NULL) { free(path); FindClose(hFile); return 0; }
406*27162e4eSAndroid Build Coastguard Worker }
407*27162e4eSAndroid Build Coastguard Worker if (*bufStart + *pos + pathLength < *bufEnd) {
408*27162e4eSAndroid Build Coastguard Worker strncpy(*bufStart + *pos, path, *bufEnd - (*bufStart + *pos));
409*27162e4eSAndroid Build Coastguard Worker *pos += pathLength + 1;
410*27162e4eSAndroid Build Coastguard Worker nbFiles++;
411*27162e4eSAndroid Build Coastguard Worker }
412*27162e4eSAndroid Build Coastguard Worker }
413*27162e4eSAndroid Build Coastguard Worker free(path);
414*27162e4eSAndroid Build Coastguard Worker } while (FindNextFileA(hFile, &cFile));
415*27162e4eSAndroid Build Coastguard Worker
416*27162e4eSAndroid Build Coastguard Worker FindClose(hFile);
417*27162e4eSAndroid Build Coastguard Worker assert(nbFiles < INT_MAX);
418*27162e4eSAndroid Build Coastguard Worker return (int)nbFiles;
419*27162e4eSAndroid Build Coastguard Worker }
420*27162e4eSAndroid Build Coastguard Worker
421*27162e4eSAndroid Build Coastguard Worker #elif defined(__linux__) || (PLATFORM_POSIX_VERSION >= 200112L) /* opendir, readdir require POSIX.1-2001 */
422*27162e4eSAndroid Build Coastguard Worker # define UTIL_HAS_CREATEFILELIST
423*27162e4eSAndroid Build Coastguard Worker # include <dirent.h> /* opendir, readdir */
424*27162e4eSAndroid Build Coastguard Worker # include <string.h> /* strerror, memcpy */
425*27162e4eSAndroid Build Coastguard Worker
UTIL_prepareFileList(const char * dirName,char ** bufStart,size_t * pos,char ** bufEnd)426*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC int UTIL_prepareFileList(const char* dirName, char** bufStart, size_t* pos, char** bufEnd)
427*27162e4eSAndroid Build Coastguard Worker {
428*27162e4eSAndroid Build Coastguard Worker DIR* dir;
429*27162e4eSAndroid Build Coastguard Worker struct dirent * entry;
430*27162e4eSAndroid Build Coastguard Worker size_t dirLength;
431*27162e4eSAndroid Build Coastguard Worker int nbFiles = 0;
432*27162e4eSAndroid Build Coastguard Worker
433*27162e4eSAndroid Build Coastguard Worker if (!(dir = opendir(dirName))) {
434*27162e4eSAndroid Build Coastguard Worker fprintf(stderr, "Cannot open directory '%s': %s\n", dirName, strerror(errno));
435*27162e4eSAndroid Build Coastguard Worker return 0;
436*27162e4eSAndroid Build Coastguard Worker }
437*27162e4eSAndroid Build Coastguard Worker
438*27162e4eSAndroid Build Coastguard Worker dirLength = strlen(dirName);
439*27162e4eSAndroid Build Coastguard Worker errno = 0;
440*27162e4eSAndroid Build Coastguard Worker while ((entry = readdir(dir)) != NULL) {
441*27162e4eSAndroid Build Coastguard Worker char* path;
442*27162e4eSAndroid Build Coastguard Worker size_t fnameLength, pathLength;
443*27162e4eSAndroid Build Coastguard Worker if (strcmp (entry->d_name, "..") == 0 ||
444*27162e4eSAndroid Build Coastguard Worker strcmp (entry->d_name, ".") == 0) continue;
445*27162e4eSAndroid Build Coastguard Worker fnameLength = strlen(entry->d_name);
446*27162e4eSAndroid Build Coastguard Worker path = (char*)malloc(dirLength + fnameLength + 2);
447*27162e4eSAndroid Build Coastguard Worker if (!path) { closedir(dir); return 0; }
448*27162e4eSAndroid Build Coastguard Worker memcpy(path, dirName, dirLength);
449*27162e4eSAndroid Build Coastguard Worker path[dirLength] = '/';
450*27162e4eSAndroid Build Coastguard Worker memcpy(path+dirLength+1, entry->d_name, fnameLength);
451*27162e4eSAndroid Build Coastguard Worker pathLength = dirLength+1+fnameLength;
452*27162e4eSAndroid Build Coastguard Worker path[pathLength] = 0;
453*27162e4eSAndroid Build Coastguard Worker
454*27162e4eSAndroid Build Coastguard Worker if (UTIL_isDirectory(path)) {
455*27162e4eSAndroid Build Coastguard Worker nbFiles += UTIL_prepareFileList(path, bufStart, pos, bufEnd); /* Recursively call "UTIL_prepareFileList" with the new path. */
456*27162e4eSAndroid Build Coastguard Worker if (*bufStart == NULL) { free(path); closedir(dir); return 0; }
457*27162e4eSAndroid Build Coastguard Worker } else {
458*27162e4eSAndroid Build Coastguard Worker if (*bufStart + *pos + pathLength >= *bufEnd) {
459*27162e4eSAndroid Build Coastguard Worker size_t const newListSize = (size_t)(*bufEnd - *bufStart) + LIST_SIZE_INCREASE;
460*27162e4eSAndroid Build Coastguard Worker *bufStart = (char*)UTIL_realloc(*bufStart, newListSize);
461*27162e4eSAndroid Build Coastguard Worker *bufEnd = *bufStart + newListSize;
462*27162e4eSAndroid Build Coastguard Worker if (*bufStart == NULL) { free(path); closedir(dir); return 0; }
463*27162e4eSAndroid Build Coastguard Worker }
464*27162e4eSAndroid Build Coastguard Worker if (*bufStart + *pos + pathLength < *bufEnd) {
465*27162e4eSAndroid Build Coastguard Worker strncpy(*bufStart + *pos, path, *bufEnd - (*bufStart + *pos));
466*27162e4eSAndroid Build Coastguard Worker *pos += pathLength + 1;
467*27162e4eSAndroid Build Coastguard Worker nbFiles++;
468*27162e4eSAndroid Build Coastguard Worker }
469*27162e4eSAndroid Build Coastguard Worker }
470*27162e4eSAndroid Build Coastguard Worker free(path);
471*27162e4eSAndroid Build Coastguard Worker errno = 0; /* clear errno after UTIL_isDirectory, UTIL_prepareFileList */
472*27162e4eSAndroid Build Coastguard Worker }
473*27162e4eSAndroid Build Coastguard Worker
474*27162e4eSAndroid Build Coastguard Worker if (errno != 0) {
475*27162e4eSAndroid Build Coastguard Worker fprintf(stderr, "readdir(%s) error: %s\n", dirName, strerror(errno));
476*27162e4eSAndroid Build Coastguard Worker free(*bufStart);
477*27162e4eSAndroid Build Coastguard Worker *bufStart = NULL;
478*27162e4eSAndroid Build Coastguard Worker }
479*27162e4eSAndroid Build Coastguard Worker closedir(dir);
480*27162e4eSAndroid Build Coastguard Worker return nbFiles;
481*27162e4eSAndroid Build Coastguard Worker }
482*27162e4eSAndroid Build Coastguard Worker
483*27162e4eSAndroid Build Coastguard Worker #else
484*27162e4eSAndroid Build Coastguard Worker
UTIL_prepareFileList(const char * dirName,char ** bufStart,size_t * pos,char ** bufEnd)485*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC int UTIL_prepareFileList(const char* dirName, char** bufStart, size_t* pos, char** bufEnd)
486*27162e4eSAndroid Build Coastguard Worker {
487*27162e4eSAndroid Build Coastguard Worker (void)bufStart; (void)bufEnd; (void)pos;
488*27162e4eSAndroid Build Coastguard Worker fprintf(stderr, "Directory %s ignored (compiled without _WIN32 or _POSIX_C_SOURCE)\n", dirName);
489*27162e4eSAndroid Build Coastguard Worker return 0;
490*27162e4eSAndroid Build Coastguard Worker }
491*27162e4eSAndroid Build Coastguard Worker
492*27162e4eSAndroid Build Coastguard Worker #endif /* #ifdef _WIN32 */
493*27162e4eSAndroid Build Coastguard Worker
494*27162e4eSAndroid Build Coastguard Worker /*
495*27162e4eSAndroid Build Coastguard Worker * UTIL_createFileList - takes a list of files and directories (params: inputNames, inputNamesNb), scans directories,
496*27162e4eSAndroid Build Coastguard Worker * and returns a new list of files (params: return value, allocatedBuffer, allocatedNamesNb).
497*27162e4eSAndroid Build Coastguard Worker * After finishing usage of the list the structures should be freed with UTIL_freeFileList(params: return value, allocatedBuffer)
498*27162e4eSAndroid Build Coastguard Worker * In case of error UTIL_createFileList returns NULL and UTIL_freeFileList should not be called.
499*27162e4eSAndroid Build Coastguard Worker */
500*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC const char**
UTIL_createFileList(const char ** inputNames,unsigned inputNamesNb,char ** allocatedBuffer,unsigned * allocatedNamesNb)501*27162e4eSAndroid Build Coastguard Worker UTIL_createFileList(const char** inputNames, unsigned inputNamesNb,
502*27162e4eSAndroid Build Coastguard Worker char** allocatedBuffer, unsigned* allocatedNamesNb)
503*27162e4eSAndroid Build Coastguard Worker {
504*27162e4eSAndroid Build Coastguard Worker size_t pos;
505*27162e4eSAndroid Build Coastguard Worker unsigned i, nbFiles;
506*27162e4eSAndroid Build Coastguard Worker char* buf = (char*)malloc(LIST_SIZE_INCREASE);
507*27162e4eSAndroid Build Coastguard Worker size_t bufSize = LIST_SIZE_INCREASE;
508*27162e4eSAndroid Build Coastguard Worker const char** fileTable;
509*27162e4eSAndroid Build Coastguard Worker
510*27162e4eSAndroid Build Coastguard Worker if (!buf) return NULL;
511*27162e4eSAndroid Build Coastguard Worker
512*27162e4eSAndroid Build Coastguard Worker for (i=0, pos=0, nbFiles=0; i<inputNamesNb; i++) {
513*27162e4eSAndroid Build Coastguard Worker if (!UTIL_isDirectory(inputNames[i])) {
514*27162e4eSAndroid Build Coastguard Worker size_t const len = strlen(inputNames[i]) + 1; /* include nul char */
515*27162e4eSAndroid Build Coastguard Worker if (pos + len >= bufSize) {
516*27162e4eSAndroid Build Coastguard Worker while (pos + len >= bufSize) bufSize += LIST_SIZE_INCREASE;
517*27162e4eSAndroid Build Coastguard Worker buf = (char*)UTIL_realloc(buf, bufSize);
518*27162e4eSAndroid Build Coastguard Worker if (!buf) return NULL;
519*27162e4eSAndroid Build Coastguard Worker }
520*27162e4eSAndroid Build Coastguard Worker assert(pos + len < bufSize);
521*27162e4eSAndroid Build Coastguard Worker memcpy(buf + pos, inputNames[i], len);
522*27162e4eSAndroid Build Coastguard Worker pos += len;
523*27162e4eSAndroid Build Coastguard Worker nbFiles++;
524*27162e4eSAndroid Build Coastguard Worker } else {
525*27162e4eSAndroid Build Coastguard Worker char* bufend = buf + bufSize;
526*27162e4eSAndroid Build Coastguard Worker nbFiles += (unsigned)UTIL_prepareFileList(inputNames[i], &buf, &pos, &bufend);
527*27162e4eSAndroid Build Coastguard Worker if (buf == NULL) return NULL;
528*27162e4eSAndroid Build Coastguard Worker assert(bufend > buf);
529*27162e4eSAndroid Build Coastguard Worker bufSize = (size_t)(bufend - buf);
530*27162e4eSAndroid Build Coastguard Worker } }
531*27162e4eSAndroid Build Coastguard Worker
532*27162e4eSAndroid Build Coastguard Worker if (nbFiles == 0) { free(buf); return NULL; }
533*27162e4eSAndroid Build Coastguard Worker
534*27162e4eSAndroid Build Coastguard Worker fileTable = (const char**)malloc(((size_t)nbFiles+1) * sizeof(const char*));
535*27162e4eSAndroid Build Coastguard Worker if (!fileTable) { free(buf); return NULL; }
536*27162e4eSAndroid Build Coastguard Worker
537*27162e4eSAndroid Build Coastguard Worker for (i=0, pos=0; i<nbFiles; i++) {
538*27162e4eSAndroid Build Coastguard Worker fileTable[i] = buf + pos;
539*27162e4eSAndroid Build Coastguard Worker pos += strlen(fileTable[i]) + 1;
540*27162e4eSAndroid Build Coastguard Worker }
541*27162e4eSAndroid Build Coastguard Worker
542*27162e4eSAndroid Build Coastguard Worker if (pos > bufSize) {
543*27162e4eSAndroid Build Coastguard Worker free(buf);
544*27162e4eSAndroid Build Coastguard Worker free((void*)fileTable);
545*27162e4eSAndroid Build Coastguard Worker return NULL;
546*27162e4eSAndroid Build Coastguard Worker } /* can this happen ? */
547*27162e4eSAndroid Build Coastguard Worker
548*27162e4eSAndroid Build Coastguard Worker *allocatedBuffer = buf;
549*27162e4eSAndroid Build Coastguard Worker *allocatedNamesNb = nbFiles;
550*27162e4eSAndroid Build Coastguard Worker
551*27162e4eSAndroid Build Coastguard Worker return fileTable;
552*27162e4eSAndroid Build Coastguard Worker }
553*27162e4eSAndroid Build Coastguard Worker
554*27162e4eSAndroid Build Coastguard Worker
555*27162e4eSAndroid Build Coastguard Worker UTIL_STATIC void
UTIL_freeFileList(const char ** filenameTable,char * allocatedBuffer)556*27162e4eSAndroid Build Coastguard Worker UTIL_freeFileList(const char** filenameTable, char* allocatedBuffer)
557*27162e4eSAndroid Build Coastguard Worker {
558*27162e4eSAndroid Build Coastguard Worker free(allocatedBuffer);
559*27162e4eSAndroid Build Coastguard Worker free((void*)filenameTable);
560*27162e4eSAndroid Build Coastguard Worker }
561*27162e4eSAndroid Build Coastguard Worker
562*27162e4eSAndroid Build Coastguard Worker
563*27162e4eSAndroid Build Coastguard Worker #if defined (__cplusplus)
564*27162e4eSAndroid Build Coastguard Worker }
565*27162e4eSAndroid Build Coastguard Worker #endif
566*27162e4eSAndroid Build Coastguard Worker
567*27162e4eSAndroid Build Coastguard Worker #endif /* UTIL_H_MODULE */
568