simdjson 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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))