simdjson 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/.clang-format +5 -0
  3. data/.gitignore +14 -0
  4. data/.gitmodules +3 -0
  5. data/.rubocop.yml +9 -0
  6. data/.travis.yml +7 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +39 -0
  10. data/Rakefile +32 -0
  11. data/benchmark/apache_builds.json +4421 -0
  12. data/benchmark/demo.json +15 -0
  13. data/benchmark/github_events.json +1390 -0
  14. data/benchmark/run_benchmark.rb +30 -0
  15. data/ext/simdjson/extconf.rb +22 -0
  16. data/ext/simdjson/simdjson.cpp +76 -0
  17. data/ext/simdjson/simdjson.hpp +6 -0
  18. data/lib/simdjson/version.rb +3 -0
  19. data/lib/simdjson.rb +2 -0
  20. data/simdjson.gemspec +35 -0
  21. data/vendor/.gitkeep +0 -0
  22. data/vendor/simdjson/AUTHORS +3 -0
  23. data/vendor/simdjson/CMakeLists.txt +63 -0
  24. data/vendor/simdjson/CONTRIBUTORS +27 -0
  25. data/vendor/simdjson/Dockerfile +10 -0
  26. data/vendor/simdjson/LICENSE +201 -0
  27. data/vendor/simdjson/Makefile +203 -0
  28. data/vendor/simdjson/Notes.md +85 -0
  29. data/vendor/simdjson/README.md +581 -0
  30. data/vendor/simdjson/amalgamation.sh +158 -0
  31. data/vendor/simdjson/benchmark/CMakeLists.txt +8 -0
  32. data/vendor/simdjson/benchmark/benchmark.h +223 -0
  33. data/vendor/simdjson/benchmark/distinctuseridcompetition.cpp +347 -0
  34. data/vendor/simdjson/benchmark/linux/linux-perf-events.h +93 -0
  35. data/vendor/simdjson/benchmark/minifiercompetition.cpp +181 -0
  36. data/vendor/simdjson/benchmark/parse.cpp +393 -0
  37. data/vendor/simdjson/benchmark/parseandstatcompetition.cpp +305 -0
  38. data/vendor/simdjson/benchmark/parsingcompetition.cpp +298 -0
  39. data/vendor/simdjson/benchmark/statisticalmodel.cpp +208 -0
  40. data/vendor/simdjson/dependencies/jsoncppdist/json/json-forwards.h +344 -0
  41. data/vendor/simdjson/dependencies/jsoncppdist/json/json.h +2366 -0
  42. data/vendor/simdjson/dependencies/jsoncppdist/jsoncpp.cpp +5418 -0
  43. data/vendor/simdjson/doc/apache_builds.jsonparseandstat.png +0 -0
  44. data/vendor/simdjson/doc/gbps.png +0 -0
  45. data/vendor/simdjson/doc/github_events.jsonparseandstat.png +0 -0
  46. data/vendor/simdjson/doc/twitter.jsonparseandstat.png +0 -0
  47. data/vendor/simdjson/doc/update-center.jsonparseandstat.png +0 -0
  48. data/vendor/simdjson/images/halvarflake.png +0 -0
  49. data/vendor/simdjson/images/logo.png +0 -0
  50. data/vendor/simdjson/include/simdjson/common_defs.h +102 -0
  51. data/vendor/simdjson/include/simdjson/isadetection.h +152 -0
  52. data/vendor/simdjson/include/simdjson/jsoncharutils.h +301 -0
  53. data/vendor/simdjson/include/simdjson/jsonformatutils.h +202 -0
  54. data/vendor/simdjson/include/simdjson/jsonioutil.h +32 -0
  55. data/vendor/simdjson/include/simdjson/jsonminifier.h +30 -0
  56. data/vendor/simdjson/include/simdjson/jsonparser.h +250 -0
  57. data/vendor/simdjson/include/simdjson/numberparsing.h +587 -0
  58. data/vendor/simdjson/include/simdjson/padded_string.h +70 -0
  59. data/vendor/simdjson/include/simdjson/parsedjson.h +544 -0
  60. data/vendor/simdjson/include/simdjson/portability.h +172 -0
  61. data/vendor/simdjson/include/simdjson/simdjson.h +44 -0
  62. data/vendor/simdjson/include/simdjson/simdjson_version.h +13 -0
  63. data/vendor/simdjson/include/simdjson/simdprune_tables.h +35074 -0
  64. data/vendor/simdjson/include/simdjson/simdutf8check_arm64.h +180 -0
  65. data/vendor/simdjson/include/simdjson/simdutf8check_haswell.h +198 -0
  66. data/vendor/simdjson/include/simdjson/simdutf8check_westmere.h +169 -0
  67. data/vendor/simdjson/include/simdjson/stage1_find_marks.h +121 -0
  68. data/vendor/simdjson/include/simdjson/stage1_find_marks_arm64.h +210 -0
  69. data/vendor/simdjson/include/simdjson/stage1_find_marks_flatten.h +93 -0
  70. data/vendor/simdjson/include/simdjson/stage1_find_marks_flatten_haswell.h +95 -0
  71. data/vendor/simdjson/include/simdjson/stage1_find_marks_haswell.h +210 -0
  72. data/vendor/simdjson/include/simdjson/stage1_find_marks_macros.h +239 -0
  73. data/vendor/simdjson/include/simdjson/stage1_find_marks_westmere.h +194 -0
  74. data/vendor/simdjson/include/simdjson/stage2_build_tape.h +85 -0
  75. data/vendor/simdjson/include/simdjson/stringparsing.h +105 -0
  76. data/vendor/simdjson/include/simdjson/stringparsing_arm64.h +56 -0
  77. data/vendor/simdjson/include/simdjson/stringparsing_haswell.h +43 -0
  78. data/vendor/simdjson/include/simdjson/stringparsing_macros.h +88 -0
  79. data/vendor/simdjson/include/simdjson/stringparsing_westmere.h +41 -0
  80. data/vendor/simdjson/jsonexamples/small/jsoniter_scala/README.md +4 -0
  81. data/vendor/simdjson/scripts/dumpsimplestats.sh +11 -0
  82. data/vendor/simdjson/scripts/issue150.sh +14 -0
  83. data/vendor/simdjson/scripts/javascript/README.md +3 -0
  84. data/vendor/simdjson/scripts/javascript/generatelargejson.js +19 -0
  85. data/vendor/simdjson/scripts/minifier.sh +11 -0
  86. data/vendor/simdjson/scripts/parseandstat.sh +24 -0
  87. data/vendor/simdjson/scripts/parser.sh +11 -0
  88. data/vendor/simdjson/scripts/parsingcompdata.sh +26 -0
  89. data/vendor/simdjson/scripts/plotparse.sh +98 -0
  90. data/vendor/simdjson/scripts/selectparser.sh +11 -0
  91. data/vendor/simdjson/scripts/setupfortesting/disablehyperthreading.sh +15 -0
  92. data/vendor/simdjson/scripts/setupfortesting/powerpolicy.sh +32 -0
  93. data/vendor/simdjson/scripts/setupfortesting/setupfortesting.sh +6 -0
  94. data/vendor/simdjson/scripts/setupfortesting/turboboost.sh +51 -0
  95. data/vendor/simdjson/scripts/testjson2json.sh +99 -0
  96. data/vendor/simdjson/scripts/transitions/Makefile +10 -0
  97. data/vendor/simdjson/scripts/transitions/generatetransitions.cpp +20 -0
  98. data/vendor/simdjson/singleheader/README.md +1 -0
  99. data/vendor/simdjson/singleheader/amalgamation_demo.cpp +20 -0
  100. data/vendor/simdjson/singleheader/simdjson.cpp +1652 -0
  101. data/vendor/simdjson/singleheader/simdjson.h +39692 -0
  102. data/vendor/simdjson/src/CMakeLists.txt +67 -0
  103. data/vendor/simdjson/src/jsonioutil.cpp +35 -0
  104. data/vendor/simdjson/src/jsonminifier.cpp +285 -0
  105. data/vendor/simdjson/src/jsonparser.cpp +91 -0
  106. data/vendor/simdjson/src/parsedjson.cpp +323 -0
  107. data/vendor/simdjson/src/parsedjsoniterator.cpp +272 -0
  108. data/vendor/simdjson/src/simdjson.cpp +30 -0
  109. data/vendor/simdjson/src/stage1_find_marks.cpp +41 -0
  110. data/vendor/simdjson/src/stage2_build_tape.cpp +567 -0
  111. data/vendor/simdjson/style/clang-format-check.sh +25 -0
  112. data/vendor/simdjson/style/clang-format.sh +25 -0
  113. data/vendor/simdjson/style/run-clang-format.py +326 -0
  114. data/vendor/simdjson/tape.md +134 -0
  115. data/vendor/simdjson/tests/CMakeLists.txt +25 -0
  116. data/vendor/simdjson/tests/allparserscheckfile.cpp +192 -0
  117. data/vendor/simdjson/tests/basictests.cpp +75 -0
  118. data/vendor/simdjson/tests/jsoncheck.cpp +136 -0
  119. data/vendor/simdjson/tests/numberparsingcheck.cpp +224 -0
  120. data/vendor/simdjson/tests/pointercheck.cpp +38 -0
  121. data/vendor/simdjson/tests/singleheadertest.cpp +22 -0
  122. data/vendor/simdjson/tests/stringparsingcheck.cpp +408 -0
  123. data/vendor/simdjson/tools/CMakeLists.txt +3 -0
  124. data/vendor/simdjson/tools/cmake/FindCTargets.cmake +15 -0
  125. data/vendor/simdjson/tools/cmake/FindOptions.cmake +52 -0
  126. data/vendor/simdjson/tools/json2json.cpp +112 -0
  127. data/vendor/simdjson/tools/jsonpointer.cpp +93 -0
  128. data/vendor/simdjson/tools/jsonstats.cpp +143 -0
  129. data/vendor/simdjson/tools/minify.cpp +21 -0
  130. data/vendor/simdjson/tools/release.py +125 -0
  131. data/vendor/simdjson/windows/dirent_portable.h +1043 -0
  132. metadata +273 -0
@@ -0,0 +1,1043 @@
1
+ // only use under Visual Studio and only for jsoncheck.cpp
2
+ /*
3
+ * This file was originally: "dirent for Visual C++" from: http://softagalleria.net/dirent.php (version 1.20.1)
4
+ * However I've modified it to <dirent_portable.h> by adding:
5
+ *
6
+ * a fallback to <dirent.h> if _WIN32 is not defined
7
+ * two missing methods: scandir(...) and alphasort(...)
8
+ * and some other minor modifications (see below)
9
+ *
10
+ *
11
+ * Original license from http://softagalleria.net/dirent.php
12
+ *
13
+ *========================================================================
14
+ *
15
+ * dirent.h - dirent API for Microsoft Visual Studio
16
+ *
17
+ * Copyright (C) 2006-2012 Toni Ronkko
18
+ *
19
+ * Permission is hereby granted, free of charge, to any person obtaining
20
+ * a copy of this software and associated documentation files (the
21
+ * ``Software''), to deal in the Software without restriction, including
22
+ * without limitation the rights to use, copy, modify, merge, publish,
23
+ * distribute, sublicense, and/or sell copies of the Software, and to
24
+ * permit persons to whom the Software is furnished to do so, subject to
25
+ * the following conditions:
26
+ *
27
+ * The above copyright notice and this permission notice shall be included
28
+ * in all copies or substantial portions of the Software.
29
+ *
30
+ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
31
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
33
+ * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
34
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
35
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
36
+ * OTHER DEALINGS IN THE SOFTWARE.
37
+ *
38
+ * $Id: dirent.h,v 1.20 2014/03/19 17:52:23 tronkko Exp $
39
+ *
40
+ * =========================================================================
41
+ * Added:
42
+ * -> some undefs to prevent possible compiler warnings
43
+ * -> the scandir(...) and alphasort(...) methods
44
+ * -> the optional DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS definition (needed for browsing with short ASCII paths instead of long UTF8 paths).
45
+ * WARNING: in my tests the usage of the long UTF8 paths is not fully functional (patches are welcome)
46
+ * All these additions have been made to made <dirent_portable.h> usage for Windows consistent
47
+ * with what I get using <direct.h> under my Ubuntu Linux OS.
48
+ * =========================================================================
49
+ *
50
+ * The code of the scandir(...) method come from the musl library (http://www.musl-libc.org/)
51
+ * (MIT licensed, Copyright © 2005-2014 Rich Felker, et al.).
52
+ *
53
+ * The code of the alphasort(...) method and of all the other minor modifications is in the public domain.
54
+ *
55
+ */
56
+
57
+ #if (!defined(_WIN32) && !defined(_WIN64))
58
+ # include <dirent.h>
59
+ #else // #if (!defined(_WIN32) && !defined(_WIN64))
60
+
61
+ #ifndef DIRENT_H
62
+ #define DIRENT_H
63
+
64
+ /*
65
+ * Define architecture flags so we don't need to include windows.h.
66
+ * Avoiding windows.h makes it simpler to use windows sockets in conjunction
67
+ * with dirent.h.
68
+ */
69
+ #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
70
+ # define _X86_
71
+ #endif
72
+ #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
73
+ #define _AMD64_
74
+ #endif
75
+ #include <stringapiset.h>
76
+ #include <stdio.h>
77
+ #include <stdarg.h>
78
+ #include <windef.h> // MAX_PATH is defined here,
79
+ #include <winbase.h>
80
+ #include <wchar.h>
81
+ #include <string.h>
82
+ #include <stdlib.h>
83
+ #include <malloc.h>
84
+ #include <sys/types.h>
85
+ #include <sys/stat.h>
86
+ #include <errno.h>
87
+ #if (!defined(SIZE_MAX) && !defined(INT_MAX))
88
+ #include <limits.h> // INT_MAX
89
+ #endif //(!defined(SIZE_MAX) && !defined(INT_MAX))
90
+
91
+
92
+ //#define DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS // set it globally, not just here]
93
+
94
+ /* Indicates that d_type field is available in dirent structure */
95
+ #define _DIRENT_HAVE_D_TYPE
96
+
97
+ /* Indicates that d_namlen field is available in dirent structure */
98
+ #define _DIRENT_HAVE_D_NAMLEN
99
+
100
+ /* Entries missing from MSVC 6.0 */
101
+ #if !defined(FILE_ATTRIBUTE_DEVICE)
102
+ # define FILE_ATTRIBUTE_DEVICE 0x40
103
+ #endif
104
+
105
+ /* File type and permission flags for stat() */
106
+ #if !defined(S_IFMT)
107
+ # define S_IFMT _S_IFMT /* File type mask */
108
+ #endif
109
+ #if !defined(S_IFDIR)
110
+ # define S_IFDIR _S_IFDIR /* Directory */
111
+ #endif
112
+ #if !defined(S_IFCHR)
113
+ # define S_IFCHR _S_IFCHR /* Character device */
114
+ #endif
115
+ #if !defined(S_IFFIFO)
116
+ # define S_IFFIFO _S_IFFIFO /* Pipe */
117
+ #endif
118
+ #if !defined(S_IFREG)
119
+ # define S_IFREG _S_IFREG /* Regular file */
120
+ #endif
121
+ #if !defined(S_IREAD)
122
+ # define S_IREAD _S_IREAD /* Read permission */
123
+ #endif
124
+ #if !defined(S_IWRITE)
125
+ # define S_IWRITE _S_IWRITE /* Write permission */
126
+ #endif
127
+ #if !defined(S_IEXEC)
128
+ # define S_IEXEC _S_IEXEC /* Execute permission */
129
+ #endif
130
+ #if !defined(S_IFIFO)
131
+ # define S_IFIFO _S_IFIFO /* Pipe */
132
+ #endif
133
+ #if !defined(S_IFBLK)
134
+ # define S_IFBLK 0 /* Block device */
135
+ #endif
136
+ #if !defined(S_IFLNK)
137
+ # define S_IFLNK 0 /* Link */
138
+ #endif
139
+ #if !defined(S_IFSOCK)
140
+ # define S_IFSOCK 0 /* Socket */
141
+ #endif
142
+
143
+ #if defined(_MSC_VER)
144
+ # define S_IRUSR S_IREAD /* Read user */
145
+ # define S_IWUSR S_IWRITE /* Write user */
146
+ # define S_IXUSR 0 /* Execute user */
147
+ # define S_IRGRP 0 /* Read group */
148
+ # define S_IWGRP 0 /* Write group */
149
+ # define S_IXGRP 0 /* Execute group */
150
+ # define S_IROTH 0 /* Read others */
151
+ # define S_IWOTH 0 /* Write others */
152
+ # define S_IXOTH 0 /* Execute others */
153
+ #endif
154
+
155
+ /* Maximum length of file name */
156
+ #ifndef DIRENT_MAX_PATH
157
+ # ifndef MAX_PATH
158
+ # define MAX_PATH PATH_MAX // it should be in <limits.h> AFAIK
159
+ # endif //MAX_PATH
160
+ # ifndef DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS // utf8 strings can have up to 4 bytes per char
161
+ # define DIRENT_MAX_PATH (MAX_PATH*4)
162
+ # else //DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
163
+ # define DIRENT_MAX_PATH (MAX_PATH)
164
+ # endif //DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
165
+ #endif //DIRENT_MAX_PATH
166
+
167
+ /* File type flags for d_type */
168
+ #define DT_UNKNOWN 0
169
+ #define DT_REG S_IFREG
170
+ #define DT_DIR S_IFDIR
171
+ #define DT_FIFO S_IFIFO
172
+ #define DT_SOCK S_IFSOCK
173
+ #define DT_CHR S_IFCHR
174
+ #define DT_BLK S_IFBLK
175
+ #define DT_LNK S_IFLNK
176
+
177
+ /* Macros for converting between st_mode and d_type */
178
+ #define IFTODT(mode) ((mode) & S_IFMT)
179
+ #define DTTOIF(type) (type)
180
+
181
+ /*
182
+ * File type macros. Note that block devices, sockets and links cannot be
183
+ * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
184
+ * only defined for compatibility. These macros should always return false
185
+ * on Windows.
186
+ */
187
+
188
+ // Added some undefs to prevent possible compiler warnings
189
+ #undef S_ISFIFO
190
+ #undef S_ISDIR
191
+ #undef S_ISREG
192
+ #undef S_ISLNK
193
+ #undef S_ISSOCK
194
+ #undef S_ISSOCK
195
+ #undef S_ISCHR
196
+ #undef S_ISBLK
197
+
198
+ #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
199
+ #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
200
+ #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
201
+ #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
202
+ #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
203
+ #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
204
+ #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
205
+
206
+ /* Return the exact length of d_namlen without zero terminator */
207
+ #define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
208
+
209
+ /* Return number of bytes needed to store d_namlen */
210
+ #define _D_ALLOC_NAMLEN(p) (DIRENT_MAX_PATH)
211
+
212
+
213
+ #ifdef __cplusplus
214
+ extern "C" {
215
+ #endif
216
+
217
+
218
+ /* Wide-character version */
219
+ struct _wdirent {
220
+ long d_ino; /* Always zero */
221
+ unsigned short d_reclen; /* Structure size */
222
+ size_t d_namlen; /* Length of name without \0 */
223
+ int d_type; /* File type */
224
+ wchar_t d_name[DIRENT_MAX_PATH]; /* File name */
225
+ };
226
+ typedef struct _wdirent _wdirent;
227
+
228
+ struct _WDIR {
229
+ struct _wdirent ent; /* Current directory entry */
230
+ WIN32_FIND_DATAW data; /* Private file data */
231
+ int cached; /* True if data is valid */
232
+ HANDLE handle; /* Win32 search handle */
233
+ wchar_t *patt; /* Initial directory name */
234
+ };
235
+ typedef struct _WDIR _WDIR;
236
+
237
+ static _WDIR *_wopendir (const wchar_t *dirname);
238
+ static struct _wdirent *_wreaddir (_WDIR *dirp);
239
+ static int _wclosedir (_WDIR *dirp);
240
+ static void _wrewinddir (_WDIR* dirp);
241
+
242
+
243
+ /* For compatibility with Symbian */
244
+ #define wdirent _wdirent
245
+ #define WDIR _WDIR
246
+ #define wopendir _wopendir
247
+ #define wreaddir _wreaddir
248
+ #define wclosedir _wclosedir
249
+ #define wrewinddir _wrewinddir
250
+
251
+
252
+ /* Multi-byte character versions */
253
+ struct dirent {
254
+ long d_ino; /* Always zero */
255
+ unsigned short d_reclen; /* Structure size */
256
+ size_t d_namlen; /* Length of name without \0 */
257
+ int d_type; /* File type */
258
+ char d_name[DIRENT_MAX_PATH]; /* File name */
259
+ };
260
+ typedef struct dirent dirent;
261
+
262
+ struct DIR {
263
+ struct dirent ent;
264
+ struct _WDIR *wdirp;
265
+ };
266
+ typedef struct DIR DIR;
267
+
268
+ static DIR *opendir (const char *dirname);
269
+ static struct dirent *readdir (DIR *dirp);
270
+ static int closedir (DIR *dirp);
271
+ static void rewinddir (DIR* dirp);
272
+
273
+
274
+ /* Internal utility functions */
275
+ static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
276
+ static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
277
+
278
+ static int dirent_mbstowcs_s(
279
+ size_t *pReturnValue,
280
+ wchar_t *wcstr,
281
+ size_t sizeInWords,
282
+ const char *mbstr,
283
+ size_t count);
284
+
285
+ static int dirent_wcstombs_s(
286
+ size_t *pReturnValue,
287
+ char *mbstr,
288
+ size_t sizeInBytes,
289
+ const wchar_t *wcstr,
290
+ size_t count);
291
+
292
+ static void dirent_set_errno (int error);
293
+
294
+ /*
295
+ * Open directory stream DIRNAME for read and return a pointer to the
296
+ * internal working area that is used to retrieve individual directory
297
+ * entries.
298
+ */
299
+ static _WDIR*
300
+ _wopendir(
301
+ const wchar_t *dirname)
302
+ {
303
+ _WDIR *dirp = NULL;
304
+ int error;
305
+
306
+ /* Must have directory name */
307
+ if (dirname == NULL || dirname[0] == '\0') {
308
+ dirent_set_errno (ENOENT);
309
+ return NULL;
310
+ }
311
+
312
+ /* Allocate new _WDIR structure */
313
+ dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
314
+ if (dirp != NULL) {
315
+ DWORD n;
316
+
317
+ /* Reset _WDIR structure */
318
+ dirp->handle = INVALID_HANDLE_VALUE;
319
+ dirp->patt = NULL;
320
+ dirp->cached = 0;
321
+
322
+ /* Compute the length of full path plus zero terminator */
323
+ n = GetFullPathNameW (dirname, 0, NULL, NULL);
324
+
325
+ /* Allocate room for absolute directory name and search pattern */
326
+ dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
327
+ if (dirp->patt) {
328
+
329
+ /*
330
+ * Convert relative directory name to an absolute one. This
331
+ * allows rewinddir() to function correctly even when current
332
+ * working directory is changed between opendir() and rewinddir().
333
+ */
334
+ n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
335
+ if (n > 0) {
336
+ wchar_t *p;
337
+
338
+ /* Append search pattern \* to the directory name */
339
+ p = dirp->patt + n;
340
+ if (dirp->patt < p) {
341
+ switch (p[-1]) {
342
+ case '\\':
343
+ case '/':
344
+ case ':':
345
+ /* Directory ends in path separator, e.g. c:\temp\ */
346
+ /*NOP*/;
347
+ break;
348
+
349
+ default:
350
+ /* Directory name doesn't end in path separator */
351
+ *p++ = '\\';
352
+ }
353
+ }
354
+ *p++ = '*';
355
+ *p = '\0';
356
+
357
+ /* Open directory stream and retrieve the first entry */
358
+ if (dirent_first (dirp)) {
359
+ /* Directory stream opened successfully */
360
+ error = 0;
361
+ } else {
362
+ /* Cannot retrieve first entry */
363
+ error = 1;
364
+ dirent_set_errno (ENOENT);
365
+ }
366
+
367
+ } else {
368
+ /* Cannot retrieve full path name */
369
+ dirent_set_errno (ENOENT);
370
+ error = 1;
371
+ }
372
+
373
+ } else {
374
+ /* Cannot allocate memory for search pattern */
375
+ error = 1;
376
+ }
377
+
378
+ } else {
379
+ /* Cannot allocate _WDIR structure */
380
+ error = 1;
381
+ }
382
+
383
+ /* Clean up in case of error */
384
+ if (error && dirp) {
385
+ _wclosedir (dirp);
386
+ dirp = NULL;
387
+ }
388
+
389
+ return dirp;
390
+ }
391
+
392
+ /*
393
+ * Read next directory entry. The directory entry is returned in dirent
394
+ * structure in the d_name field. Individual directory entries returned by
395
+ * this function include regular files, sub-directories, pseudo-directories
396
+ * "." and ".." as well as volume labels, hidden files and system files.
397
+ */
398
+ static struct _wdirent*
399
+ _wreaddir(
400
+ _WDIR *dirp)
401
+ {
402
+ WIN32_FIND_DATAW *datap;
403
+ struct _wdirent *entp;
404
+
405
+ /* Read next directory entry */
406
+ datap = dirent_next (dirp);
407
+ if (datap) {
408
+ size_t n;
409
+ DWORD attr;
410
+
411
+ /* Pointer to directory entry to return */
412
+ entp = &dirp->ent;
413
+
414
+ /*
415
+ * Copy file name as wide-character string. If the file name is too
416
+ * long to fit in to the destination buffer, then truncate file name
417
+ * to DIRENT_MAX_PATH characters and zero-terminate the buffer.
418
+ */
419
+ n = 0;
420
+ while (n + 1 < DIRENT_MAX_PATH && datap->cFileName[n] != 0) {
421
+ entp->d_name[n] = datap->cFileName[n];
422
+ n++;
423
+ }
424
+ dirp->ent.d_name[n] = 0;
425
+
426
+ /* Length of file name excluding zero terminator */
427
+ entp->d_namlen = n;
428
+
429
+ /* File type */
430
+ attr = datap->dwFileAttributes;
431
+ if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
432
+ entp->d_type = DT_CHR;
433
+ } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
434
+ entp->d_type = DT_DIR;
435
+ } else {
436
+ entp->d_type = DT_REG;
437
+ }
438
+
439
+ /* Reset dummy fields */
440
+ entp->d_ino = 0;
441
+ entp->d_reclen = sizeof (struct _wdirent);
442
+
443
+ } else {
444
+
445
+ /* Last directory entry read */
446
+ entp = NULL;
447
+
448
+ }
449
+
450
+ return entp;
451
+ }
452
+
453
+ /*
454
+ * Close directory stream opened by opendir() function. This invalidates the
455
+ * DIR structure as well as any directory entry read previously by
456
+ * _wreaddir().
457
+ */
458
+ static int
459
+ _wclosedir(
460
+ _WDIR *dirp)
461
+ {
462
+ int ok;
463
+ if (dirp) {
464
+
465
+ /* Release search handle */
466
+ if (dirp->handle != INVALID_HANDLE_VALUE) {
467
+ FindClose (dirp->handle);
468
+ dirp->handle = INVALID_HANDLE_VALUE;
469
+ }
470
+
471
+ /* Release search pattern */
472
+ if (dirp->patt) {
473
+ free (dirp->patt);
474
+ dirp->patt = NULL;
475
+ }
476
+
477
+ /* Release directory structure */
478
+ free (dirp);
479
+ ok = /*success*/0;
480
+
481
+ } else {
482
+ /* Invalid directory stream */
483
+ dirent_set_errno (EBADF);
484
+ ok = /*failure*/-1;
485
+ }
486
+ return ok;
487
+ }
488
+
489
+ /*
490
+ * Rewind directory stream such that _wreaddir() returns the very first
491
+ * file name again.
492
+ */
493
+ static void
494
+ _wrewinddir(
495
+ _WDIR* dirp)
496
+ {
497
+ if (dirp) {
498
+ /* Release existing search handle */
499
+ if (dirp->handle != INVALID_HANDLE_VALUE) {
500
+ FindClose (dirp->handle);
501
+ }
502
+
503
+ /* Open new search handle */
504
+ dirent_first (dirp);
505
+ }
506
+ }
507
+
508
+ /* Get first directory entry (internal) */
509
+ static WIN32_FIND_DATAW*
510
+ dirent_first(
511
+ _WDIR *dirp)
512
+ {
513
+ WIN32_FIND_DATAW *datap;
514
+
515
+ /* Open directory and retrieve the first entry */
516
+ dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
517
+ if (dirp->handle != INVALID_HANDLE_VALUE) {
518
+
519
+ /* a directory entry is now waiting in memory */
520
+ datap = &dirp->data;
521
+ dirp->cached = 1;
522
+
523
+ } else {
524
+
525
+ /* Failed to re-open directory: no directory entry in memory */
526
+ dirp->cached = 0;
527
+ datap = NULL;
528
+
529
+ }
530
+ return datap;
531
+ }
532
+
533
+ /* Get next directory entry (internal) */
534
+ static WIN32_FIND_DATAW*
535
+ dirent_next(
536
+ _WDIR *dirp)
537
+ {
538
+ WIN32_FIND_DATAW *p;
539
+
540
+ /* Get next directory entry */
541
+ if (dirp->cached != 0) {
542
+
543
+ /* A valid directory entry already in memory */
544
+ p = &dirp->data;
545
+ dirp->cached = 0;
546
+
547
+ } else if (dirp->handle != INVALID_HANDLE_VALUE) {
548
+
549
+ /* Get the next directory entry from stream */
550
+ if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
551
+ /* Got a file */
552
+ p = &dirp->data;
553
+ } else {
554
+ /* The very last entry has been processed or an error occured */
555
+ FindClose (dirp->handle);
556
+ dirp->handle = INVALID_HANDLE_VALUE;
557
+ p = NULL;
558
+ }
559
+
560
+ } else {
561
+
562
+ /* End of directory stream reached */
563
+ p = NULL;
564
+
565
+ }
566
+
567
+ return p;
568
+ }
569
+
570
+ /*
571
+ * Open directory stream using plain old C-string.
572
+ */
573
+ static DIR*
574
+ opendir(
575
+ const char *dirname)
576
+ {
577
+ struct DIR *dirp;
578
+ int error;
579
+
580
+ /* Must have directory name */
581
+ if (dirname == NULL || dirname[0] == '\0') {
582
+ dirent_set_errno (ENOENT);
583
+ return NULL;
584
+ }
585
+
586
+ /* Allocate memory for DIR structure */
587
+ dirp = (DIR*) malloc (sizeof (struct DIR));
588
+ if (dirp) {
589
+ wchar_t wname[DIRENT_MAX_PATH];
590
+ size_t n;
591
+
592
+ /* Convert directory name to wide-character string */
593
+ error = dirent_mbstowcs_s (&n, wname, DIRENT_MAX_PATH, dirname, DIRENT_MAX_PATH);
594
+ if (!error) {
595
+
596
+ /* Open directory stream using wide-character name */
597
+ dirp->wdirp = _wopendir (wname);
598
+ if (dirp->wdirp) {
599
+ /* Directory stream opened */
600
+ error = 0;
601
+ } else {
602
+ /* Failed to open directory stream */
603
+ error = 1;
604
+ }
605
+
606
+ } else {
607
+ /*
608
+ * Cannot convert file name to wide-character string. This
609
+ * occurs if the string contains invalid multi-byte sequences or
610
+ * the output buffer is too small to contain the resulting
611
+ * string.
612
+ */
613
+ error = 1;
614
+ }
615
+
616
+ } else {
617
+ /* Cannot allocate DIR structure */
618
+ error = 1;
619
+ }
620
+
621
+ /* Clean up in case of error */
622
+ if (error && dirp) {
623
+ free (dirp);
624
+ dirp = NULL;
625
+ }
626
+
627
+ return dirp;
628
+ }
629
+
630
+ /*
631
+ * Read next directory entry.
632
+ *
633
+ * When working with text consoles, please note that file names returned by
634
+ * readdir() are represented in the default ANSI code page while any output to
635
+ * console is typically formatted on another code page. Thus, non-ASCII
636
+ * characters in file names will not usually display correctly on console. The
637
+ * problem can be fixed in two ways: (1) change the character set of console
638
+ * to 1252 using chcp utility and use Lucida Console font, or (2) use
639
+ * _cprintf function when writing to console. The _cprinf() will re-encode
640
+ * ANSI strings to the console code page so many non-ASCII characters will
641
+ * display correcly.
642
+ */
643
+ static struct dirent*
644
+ readdir(
645
+ DIR *dirp)
646
+ {
647
+ WIN32_FIND_DATAW *datap;
648
+ struct dirent *entp;
649
+
650
+ /* Read next directory entry */
651
+ datap = dirent_next (dirp->wdirp);
652
+ if (datap) {
653
+ size_t n;
654
+ int error;
655
+
656
+ /* Attempt to convert file name to multi-byte string */
657
+ error = dirent_wcstombs_s(
658
+ &n, dirp->ent.d_name, DIRENT_MAX_PATH, datap->cFileName, DIRENT_MAX_PATH);
659
+
660
+ /*
661
+ * If the file name cannot be represented by a multi-byte string,
662
+ * then attempt to use old 8+3 file name. This allows traditional
663
+ * Unix-code to access some file names despite of unicode
664
+ * characters, although file names may seem unfamiliar to the user.
665
+ *
666
+ * Be ware that the code below cannot come up with a short file
667
+ * name unless the file system provides one. At least
668
+ * VirtualBox shared folders fail to do this.
669
+ */
670
+ if (error && datap->cAlternateFileName[0] != '\0') {
671
+ error = dirent_wcstombs_s(
672
+ &n, dirp->ent.d_name, DIRENT_MAX_PATH,
673
+ datap->cAlternateFileName, DIRENT_MAX_PATH);
674
+ }
675
+
676
+ if (!error) {
677
+ DWORD attr;
678
+
679
+ /* Initialize directory entry for return */
680
+ entp = &dirp->ent;
681
+
682
+ /* Length of file name excluding zero terminator */
683
+ entp->d_namlen = n - 1;
684
+
685
+ /* File attributes */
686
+ attr = datap->dwFileAttributes;
687
+ if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
688
+ entp->d_type = DT_CHR;
689
+ } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
690
+ entp->d_type = DT_DIR;
691
+ } else {
692
+ entp->d_type = DT_REG;
693
+ }
694
+
695
+ /* Reset dummy fields */
696
+ entp->d_ino = 0;
697
+ entp->d_reclen = sizeof (struct dirent);
698
+
699
+ } else {
700
+ /*
701
+ * Cannot convert file name to multi-byte string so construct
702
+ * an errornous directory entry and return that. Note that
703
+ * we cannot return NULL as that would stop the processing
704
+ * of directory entries completely.
705
+ */
706
+ entp = &dirp->ent;
707
+ entp->d_name[0] = '?';
708
+ entp->d_name[1] = '\0';
709
+ entp->d_namlen = 1;
710
+ entp->d_type = DT_UNKNOWN;
711
+ entp->d_ino = 0;
712
+ entp->d_reclen = 0;
713
+ }
714
+
715
+ } else {
716
+ /* No more directory entries */
717
+ entp = NULL;
718
+ }
719
+
720
+ return entp;
721
+ }
722
+
723
+ /*
724
+ * Close directory stream.
725
+ */
726
+ static int
727
+ closedir(
728
+ DIR *dirp)
729
+ {
730
+ int ok;
731
+ if (dirp) {
732
+
733
+ /* Close wide-character directory stream */
734
+ ok = _wclosedir (dirp->wdirp);
735
+ dirp->wdirp = NULL;
736
+
737
+ /* Release multi-byte character version */
738
+ free (dirp);
739
+
740
+ } else {
741
+
742
+ /* Invalid directory stream */
743
+ dirent_set_errno (EBADF);
744
+ ok = /*failure*/-1;
745
+
746
+ }
747
+ return ok;
748
+ }
749
+
750
+ /*
751
+ * Rewind directory stream to beginning.
752
+ */
753
+ static void
754
+ rewinddir(
755
+ DIR* dirp)
756
+ {
757
+ /* Rewind wide-character string directory stream */
758
+ _wrewinddir (dirp->wdirp);
759
+ }
760
+
761
+ /* Convert multi-byte string to wide character string */
762
+ static int
763
+ dirent_mbstowcs_s(
764
+ size_t *pReturnValue,
765
+ wchar_t *wcstr,
766
+ size_t sizeInWords,
767
+ const char *mbstr,
768
+ size_t count)
769
+ {
770
+ int error;
771
+ #ifndef DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
772
+ // we don't use "count" at all: we assume mstr is zero terminated:
773
+ size_t n = (size_t) MultiByteToWideChar (CP_UTF8, 0, mbstr, -1, wcstr, 0);//sizeInWords);
774
+ if (n==0) {
775
+ error = 1;
776
+ if (sizeInWords>0) wcstr[0]=L'\0';
777
+ if (pReturnValue) *pReturnValue = 0;
778
+ }
779
+ else if (n<=sizeInWords) {
780
+ error = MultiByteToWideChar (CP_UTF8, 0, mbstr, -1, wcstr, n) == 0 ? 1 : 0;
781
+ if (pReturnValue) *pReturnValue = n;
782
+ }
783
+ else {
784
+ // Buffer too low:
785
+ if (sizeInWords>0) {
786
+ if (sizeInWords>1) MultiByteToWideChar (CP_UTF8, 0, mbstr, -1, wcstr, sizeInWords-1);
787
+ wcstr[sizeInWords-1] = L'\0';
788
+ }
789
+ if (pReturnValue) *pReturnValue = sizeInWords;
790
+ error = 1;
791
+ }
792
+
793
+ /*
794
+ if (!wcstr || n < count) {
795
+ // Zero-terminate output buffer
796
+ if (wcstr && sizeInWords) {
797
+ if (n >= sizeInWords) {
798
+ n = sizeInWords - 1;
799
+ }
800
+ wcstr[n] = 0;
801
+ }
802
+
803
+ // Length of resuting multi-byte string WITH zero terminator
804
+ if (pReturnValue) {
805
+ *pReturnValue = n + 1;
806
+ }
807
+
808
+ // Success
809
+ error = 0;
810
+
811
+ } else {
812
+
813
+ // Could not convert string
814
+ error = 1;
815
+
816
+ }
817
+ */
818
+ #else //DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
819
+ #if defined(_MSC_VER) && _MSC_VER >= 1400
820
+
821
+ /* Microsoft Visual Studio 2005 or later */
822
+ error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
823
+
824
+ #else
825
+
826
+ /* Older Visual Studio or non-Microsoft compiler */
827
+ size_t n;
828
+
829
+ /* Convert to wide-character string (or count characters) */
830
+ n = mbstowcs (wcstr, mbstr, sizeInWords);
831
+ if (!wcstr || n < count) {
832
+
833
+ /* Zero-terminate output buffer */
834
+ if (wcstr && sizeInWords) {
835
+ if (n >= sizeInWords) {
836
+ n = sizeInWords - 1;
837
+ }
838
+ wcstr[n] = 0;
839
+ }
840
+
841
+ /* Length of resuting multi-byte string WITH zero terminator */
842
+ if (pReturnValue) {
843
+ *pReturnValue = n + 1;
844
+ }
845
+
846
+ /* Success */
847
+ error = 0;
848
+
849
+ } else {
850
+
851
+ /* Could not convert string */
852
+ error = 1;
853
+
854
+ }
855
+
856
+ #endif
857
+ #endif //DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
858
+
859
+ return error;
860
+ }
861
+
862
+ /* Convert wide-character string to multi-byte string */
863
+ static int
864
+ dirent_wcstombs_s(
865
+ size_t *pReturnValue,
866
+ char *mbstr,
867
+ size_t sizeInBytes, /* max size of mbstr */
868
+ const wchar_t *wcstr,
869
+ size_t count)
870
+ {
871
+ int error;
872
+
873
+ #ifndef DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
874
+ // we don't use "count" at all: we assume wcstr is zero terminated:
875
+ size_t n = (size_t) WideCharToMultiByte (CP_UTF8, 0, wcstr, -1, mbstr, 0,NULL,NULL);//sizeInBytes, NULL, NULL);
876
+ if (n==0) {
877
+ error = 1;
878
+ if (sizeInBytes>0) mbstr[0]='\0';
879
+ if (pReturnValue) *pReturnValue = 0;
880
+ }
881
+ else if (n<=sizeInBytes) {
882
+ error = WideCharToMultiByte (CP_UTF8, 0, wcstr, -1, mbstr, n, NULL, NULL) == 0 ? 1 : 0;
883
+ if (pReturnValue) *pReturnValue = n;
884
+ }
885
+ else {
886
+ // Buffer too low:
887
+ if (sizeInBytes>0) {
888
+ if (sizeInBytes>1) WideCharToMultiByte (CP_UTF8, 0, wcstr, -1, mbstr, sizeInBytes-1, NULL, NULL);
889
+ mbstr[sizeInBytes-1] = '\0';
890
+ }
891
+ if (pReturnValue) *pReturnValue = sizeInBytes;
892
+ error = 1;
893
+ }
894
+ /*
895
+ if (!mbstr || n < count) {
896
+
897
+ // Zero-terminate output buffer
898
+ if (mbstr && sizeInBytes) {
899
+ if (n >= sizeInBytes) {
900
+ n = sizeInBytes - 1;
901
+ }
902
+ mbstr[n] = '\0';
903
+ }
904
+
905
+ // Lenght of resulting multi-bytes string WITH zero-terminator
906
+ if (pReturnValue) {
907
+ *pReturnValue = n + 1;
908
+ }
909
+
910
+
911
+ // Success
912
+ error = 0;
913
+
914
+ } else {
915
+
916
+ // Cannot convert string
917
+ error = 1;
918
+
919
+ }
920
+ */
921
+ #else //DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
922
+ #if defined(_MSC_VER) && _MSC_VER >= 1400
923
+
924
+ /* Microsoft Visual Studio 2005 or later */
925
+ error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
926
+
927
+ #else
928
+
929
+ /* Older Visual Studio or non-Microsoft compiler */
930
+ size_t n;
931
+
932
+ /* Convert to multi-byte string (or count the number of bytes needed) */
933
+ n = wcstombs (mbstr, wcstr, sizeInBytes);
934
+ if (!mbstr || n < count) {
935
+
936
+ /* Zero-terminate output buffer */
937
+ if (mbstr && sizeInBytes) {
938
+ if (n >= sizeInBytes) {
939
+ n = sizeInBytes - 1;
940
+ }
941
+ mbstr[n] = '\0';
942
+ }
943
+
944
+ /* Lenght of resulting multi-bytes string WITH zero-terminator */
945
+ if (pReturnValue) {
946
+ *pReturnValue = n + 1;
947
+ }
948
+
949
+ /* Success */
950
+ error = 0;
951
+
952
+ } else {
953
+
954
+ /* Cannot convert string */
955
+ error = 1;
956
+
957
+ }
958
+
959
+ #endif
960
+ #endif //DIRENT_USE_ASCII_SHORT_PATHS_ON_WINDOWS
961
+ return error;
962
+ }
963
+
964
+ /* Set errno variable */
965
+ static void
966
+ dirent_set_errno(
967
+ int error)
968
+ {
969
+ #if defined(_MSC_VER) && _MSC_VER >= 1400
970
+
971
+ /* Microsoft Visual Studio 2005 and later */
972
+ _set_errno (error);
973
+
974
+ #else
975
+
976
+ /* Non-Microsoft compiler or older Microsoft compiler */
977
+ errno = error;
978
+
979
+ #endif
980
+ }
981
+
982
+
983
+ // The code of this single method comes from the musl library
984
+ // (MIT licensed, Copyright © 2005-2014 Rich Felker, et al.)
985
+ # ifndef SIZE_MAX // Can't we just set it to INT_MAX or something like that ?
986
+ # define SIZE_MAX_WAS_NOT_DEFINED
987
+ # define SIZE_MAX INT_MAX // should be in limits.h AFAIK
988
+ # endif //SIZE_MAX
989
+ inline static int scandir(const char *path, struct dirent ***res,
990
+ int (*sel)(const struct dirent *),
991
+ int (*cmp)(const struct dirent **, const struct dirent **))
992
+ {
993
+ DIR *d = opendir(path);
994
+ struct dirent *de, **names=0, **tmp;
995
+ size_t cnt=0, len=0;
996
+ int old_errno = errno;
997
+
998
+ if (!d) return -1;
999
+
1000
+ while ((errno=0), (de = readdir(d))) {
1001
+ if (sel && !sel(de)) continue;
1002
+ if (cnt >= len) {
1003
+ len = 2*len+1;
1004
+ if (len > SIZE_MAX/sizeof *names) break;
1005
+ tmp = (dirent**)realloc(names, len * sizeof *names);
1006
+ if (!tmp) break;
1007
+ names = tmp;
1008
+ }
1009
+ names[cnt] = (dirent*)malloc(de->d_reclen);
1010
+ if (!names[cnt]) break;
1011
+ memcpy(names[cnt++], de, de->d_reclen);
1012
+ }
1013
+
1014
+ closedir(d);
1015
+
1016
+ if (errno) {
1017
+ if (names) while (cnt-->0) free(names[cnt]);
1018
+ free(names);
1019
+ return -1;
1020
+ }
1021
+ errno = old_errno;
1022
+
1023
+ if (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp);
1024
+ *res = names;
1025
+ return cnt;
1026
+ }
1027
+ #ifdef SIZE_MAX_WAS_NOT_DEFINED
1028
+ # undef SIZE_MAX
1029
+ # undef SIZE_MAX_WAS_NOT_DEFINED
1030
+ #endif //SIZE_MAX_WAS_NOT_DEFINED
1031
+
1032
+ // alphasort: Function to compare two `struct dirent's alphabetically.
1033
+ inline static int alphasort (const struct dirent **e1,const struct dirent **e2) {
1034
+ return strcmp((*e1)->d_name,(*e2)->d_name);
1035
+ }
1036
+
1037
+
1038
+ #ifdef __cplusplus
1039
+ }
1040
+ #endif
1041
+ #endif /*DIRENT_H*/
1042
+
1043
+ #endif //#if (!defined(_WIN32) && !defined(_WIN64))