cppjieba_rb 0.4.2 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +21 -0
  3. data/.github/workflows/linting.yml +30 -0
  4. data/.github/workflows/release.yml +42 -0
  5. data/.github/workflows/tests.yml +47 -0
  6. data/.gitignore +1 -0
  7. data/.rubocop.yml +45 -0
  8. data/.ruby-version +1 -0
  9. data/.yamllint +35 -0
  10. data/CHANGELOG.md +17 -0
  11. data/Gemfile +11 -0
  12. data/README.md +5 -5
  13. data/Rakefile +16 -7
  14. data/cppjieba_rb.gemspec +46 -33
  15. data/ext/cppjieba/.github/workflows/cmake.yml +52 -0
  16. data/ext/cppjieba/.github/workflows/stale-issues.yml +24 -0
  17. data/ext/cppjieba/.gitmodules +3 -0
  18. data/ext/cppjieba/{ChangeLog.md → CHANGELOG.md} +50 -1
  19. data/ext/cppjieba/CMakeLists.txt +11 -14
  20. data/ext/cppjieba/LICENSE +20 -0
  21. data/ext/cppjieba/README.md +9 -18
  22. data/ext/cppjieba/deps/limonp/.github/workflows/cmake.yml +43 -0
  23. data/ext/cppjieba/deps/limonp/.gitignore +9 -0
  24. data/ext/cppjieba/deps/limonp/CHANGELOG.md +160 -0
  25. data/ext/cppjieba/deps/limonp/CMakeLists.txt +61 -0
  26. data/ext/cppjieba/deps/limonp/LICENSE +20 -0
  27. data/ext/cppjieba/deps/limonp/README.md +38 -0
  28. data/ext/cppjieba/deps/limonp/{LocalVector.hpp → include/limonp/LocalVector.hpp} +3 -3
  29. data/ext/cppjieba/deps/limonp/{Logging.hpp → include/limonp/Logging.hpp} +17 -3
  30. data/ext/cppjieba/deps/limonp/{StringUtil.hpp → include/limonp/StringUtil.hpp} +31 -10
  31. data/ext/cppjieba/deps/limonp/test/CMakeLists.txt +8 -0
  32. data/ext/cppjieba/deps/limonp/test/demo.cpp +40 -0
  33. data/ext/cppjieba/deps/limonp/test/testdata/1.conf +5 -0
  34. data/ext/cppjieba/deps/limonp/test/testdata/StdExtension.data +3 -0
  35. data/ext/cppjieba/deps/limonp/test/testdata/dict.gbk +50 -0
  36. data/ext/cppjieba/deps/limonp/test/testdata/dict.utf8 +50 -0
  37. data/ext/cppjieba/deps/limonp/test/testdata/io_testfile +2 -0
  38. data/ext/cppjieba/deps/limonp/test/testdata/jieba.dict.0.1.utf8 +93 -0
  39. data/ext/cppjieba/deps/limonp/test/testdata/jieba.dict.0.utf8 +93 -0
  40. data/ext/cppjieba/deps/limonp/test/testdata/jieba.dict.1.utf8 +67 -0
  41. data/ext/cppjieba/deps/limonp/test/testdata/jieba.dict.2.utf8 +64 -0
  42. data/ext/cppjieba/deps/limonp/test/unittest/CMakeLists.txt +30 -0
  43. data/ext/cppjieba/deps/limonp/test/unittest/TArgvContext.cpp +16 -0
  44. data/ext/cppjieba/deps/limonp/test/unittest/TCastFloat.cpp +19 -0
  45. data/ext/cppjieba/deps/limonp/test/unittest/TClosure.cpp +85 -0
  46. data/ext/cppjieba/deps/limonp/test/unittest/TColorPrint.cpp +20 -0
  47. data/ext/cppjieba/deps/limonp/test/unittest/TConfig.cpp +17 -0
  48. data/ext/cppjieba/deps/limonp/test/unittest/TLocalVector.cpp +41 -0
  49. data/ext/cppjieba/deps/limonp/test/unittest/TLogging.cpp +12 -0
  50. data/ext/cppjieba/deps/limonp/test/unittest/TStdExtension.cpp +95 -0
  51. data/ext/cppjieba/deps/limonp/test/unittest/TStringUtil.cpp +183 -0
  52. data/ext/cppjieba/include/cppjieba/DictTrie.hpp +9 -0
  53. data/ext/cppjieba/include/cppjieba/Jieba.hpp +4 -0
  54. data/ext/cppjieba/include/cppjieba/Trie.hpp +27 -1
  55. data/ext/cppjieba/test/CMakeLists.txt +4 -3
  56. data/ext/cppjieba/test/unittest/CMakeLists.txt +16 -7
  57. data/ext/cppjieba_rb/extconf.rb +11 -6
  58. data/lib/cppjieba_rb/segment.rb +4 -1
  59. data/lib/cppjieba_rb/version.rb +3 -1
  60. data/lib/cppjieba_rb.rb +12 -5
  61. data/test/test_keyword.rb +8 -8
  62. data/test/test_segment.rb +14 -10
  63. data/test/test_stop_word_filter.rb +5 -3
  64. data/test/test_tagging.rb +5 -2
  65. metadata +63 -140
  66. data/.travis.yml +0 -30
  67. data/ext/cppjieba/.travis.yml +0 -21
  68. data/ext/cppjieba/README_EN.md +0 -115
  69. data/ext/cppjieba/appveyor.yml +0 -32
  70. data/ext/cppjieba/deps/CMakeLists.txt +0 -1
  71. data/ext/cppjieba/deps/gtest/CMakeLists.txt +0 -5
  72. data/ext/cppjieba/deps/gtest/include/gtest/gtest-death-test.h +0 -283
  73. data/ext/cppjieba/deps/gtest/include/gtest/gtest-message.h +0 -230
  74. data/ext/cppjieba/deps/gtest/include/gtest/gtest-param-test.h +0 -1421
  75. data/ext/cppjieba/deps/gtest/include/gtest/gtest-param-test.h.pump +0 -487
  76. data/ext/cppjieba/deps/gtest/include/gtest/gtest-printers.h +0 -796
  77. data/ext/cppjieba/deps/gtest/include/gtest/gtest-spi.h +0 -232
  78. data/ext/cppjieba/deps/gtest/include/gtest/gtest-test-part.h +0 -176
  79. data/ext/cppjieba/deps/gtest/include/gtest/gtest-typed-test.h +0 -259
  80. data/ext/cppjieba/deps/gtest/include/gtest/gtest.h +0 -2155
  81. data/ext/cppjieba/deps/gtest/include/gtest/gtest_pred_impl.h +0 -358
  82. data/ext/cppjieba/deps/gtest/include/gtest/gtest_prod.h +0 -58
  83. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-death-test-internal.h +0 -308
  84. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-filepath.h +0 -210
  85. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-internal.h +0 -1226
  86. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-linked_ptr.h +0 -233
  87. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-param-util-generated.h +0 -4822
  88. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-param-util-generated.h.pump +0 -301
  89. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-param-util.h +0 -619
  90. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-port.h +0 -1788
  91. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-string.h +0 -350
  92. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-tuple.h +0 -968
  93. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-tuple.h.pump +0 -336
  94. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-type-util.h +0 -3330
  95. data/ext/cppjieba/deps/gtest/include/gtest/internal/gtest-type-util.h.pump +0 -296
  96. data/ext/cppjieba/deps/gtest/src/.deps/gtest-all.Plo +0 -681
  97. data/ext/cppjieba/deps/gtest/src/.deps/gtest_main.Plo +0 -509
  98. data/ext/cppjieba/deps/gtest/src/.dirstamp +0 -0
  99. data/ext/cppjieba/deps/gtest/src/gtest-all.cc +0 -48
  100. data/ext/cppjieba/deps/gtest/src/gtest-death-test.cc +0 -1234
  101. data/ext/cppjieba/deps/gtest/src/gtest-filepath.cc +0 -380
  102. data/ext/cppjieba/deps/gtest/src/gtest-internal-inl.h +0 -1038
  103. data/ext/cppjieba/deps/gtest/src/gtest-port.cc +0 -746
  104. data/ext/cppjieba/deps/gtest/src/gtest-printers.cc +0 -356
  105. data/ext/cppjieba/deps/gtest/src/gtest-test-part.cc +0 -110
  106. data/ext/cppjieba/deps/gtest/src/gtest-typed-test.cc +0 -110
  107. data/ext/cppjieba/deps/gtest/src/gtest.cc +0 -4898
  108. data/ext/cppjieba/deps/limonp/BlockingQueue.hpp +0 -49
  109. data/ext/cppjieba/deps/limonp/BoundedBlockingQueue.hpp +0 -67
  110. data/ext/cppjieba/deps/limonp/BoundedQueue.hpp +0 -65
  111. data/ext/cppjieba/deps/limonp/FileLock.hpp +0 -74
  112. data/ext/cppjieba/deps/limonp/Md5.hpp +0 -411
  113. data/ext/cppjieba/deps/limonp/MutexLock.hpp +0 -51
  114. data/ext/cppjieba/deps/limonp/Thread.hpp +0 -44
  115. data/ext/cppjieba/deps/limonp/ThreadPool.hpp +0 -86
  116. data/ext/cppjieba/test/demo.cpp +0 -80
  117. /data/ext/cppjieba/deps/{gtest/src/.deps/.dirstamp → limonp/.gitmodules} +0 -0
  118. /data/ext/cppjieba/deps/limonp/{ArgvContext.hpp → include/limonp/ArgvContext.hpp} +0 -0
  119. /data/ext/cppjieba/deps/limonp/{Closure.hpp → include/limonp/Closure.hpp} +0 -0
  120. /data/ext/cppjieba/deps/limonp/{Colors.hpp → include/limonp/Colors.hpp} +0 -0
  121. /data/ext/cppjieba/deps/limonp/{Condition.hpp → include/limonp/Condition.hpp} +0 -0
  122. /data/ext/cppjieba/deps/limonp/{Config.hpp → include/limonp/Config.hpp} +0 -0
  123. /data/ext/cppjieba/deps/limonp/{ForcePublic.hpp → include/limonp/ForcePublic.hpp} +0 -0
  124. /data/ext/cppjieba/deps/limonp/{NonCopyable.hpp → include/limonp/NonCopyable.hpp} +0 -0
  125. /data/ext/cppjieba/deps/limonp/{StdExtension.hpp → include/limonp/StdExtension.hpp} +0 -0
  126. /data/ext/cppjieba/deps/{gtest/src/gtest_main.cc → limonp/test/unittest/gtest_main.cpp} +0 -0
@@ -1,380 +0,0 @@
1
- // Copyright 2008, Google Inc.
2
- // All rights reserved.
3
- //
4
- // Redistribution and use in source and binary forms, with or without
5
- // modification, are permitted provided that the following conditions are
6
- // met:
7
- //
8
- // * Redistributions of source code must retain the above copyright
9
- // notice, this list of conditions and the following disclaimer.
10
- // * Redistributions in binary form must reproduce the above
11
- // copyright notice, this list of conditions and the following disclaimer
12
- // in the documentation and/or other materials provided with the
13
- // distribution.
14
- // * Neither the name of Google Inc. nor the names of its
15
- // contributors may be used to endorse or promote products derived from
16
- // this software without specific prior written permission.
17
- //
18
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
- //
30
- // Authors: keith.ray@gmail.com (Keith Ray)
31
-
32
- #include "gtest/internal/gtest-filepath.h"
33
- #include "gtest/internal/gtest-port.h"
34
-
35
- #include <stdlib.h>
36
-
37
- #if GTEST_OS_WINDOWS_MOBILE
38
- # include <windows.h>
39
- #elif GTEST_OS_WINDOWS
40
- # include <direct.h>
41
- # include <io.h>
42
- #elif GTEST_OS_SYMBIAN || GTEST_OS_NACL
43
- // Symbian OpenC and NaCl have PATH_MAX in sys/syslimits.h
44
- # include <sys/syslimits.h>
45
- #else
46
- # include <limits.h>
47
- # include <climits> // Some Linux distributions define PATH_MAX here.
48
- #endif // GTEST_OS_WINDOWS_MOBILE
49
-
50
- #if GTEST_OS_WINDOWS
51
- # define GTEST_PATH_MAX_ _MAX_PATH
52
- #elif defined(PATH_MAX)
53
- # define GTEST_PATH_MAX_ PATH_MAX
54
- #elif defined(_XOPEN_PATH_MAX)
55
- # define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
56
- #else
57
- # define GTEST_PATH_MAX_ _POSIX_PATH_MAX
58
- #endif // GTEST_OS_WINDOWS
59
-
60
- #include "gtest/internal/gtest-string.h"
61
-
62
- namespace testing {
63
- namespace internal {
64
-
65
- #if GTEST_OS_WINDOWS
66
- // On Windows, '\\' is the standard path separator, but many tools and the
67
- // Windows API also accept '/' as an alternate path separator. Unless otherwise
68
- // noted, a file path can contain either kind of path separators, or a mixture
69
- // of them.
70
- const char kPathSeparator = '\\';
71
- const char kAlternatePathSeparator = '/';
72
- const char kPathSeparatorString[] = "\\";
73
- const char kAlternatePathSeparatorString[] = "/";
74
- # if GTEST_OS_WINDOWS_MOBILE
75
- // Windows CE doesn't have a current directory. You should not use
76
- // the current directory in tests on Windows CE, but this at least
77
- // provides a reasonable fallback.
78
- const char kCurrentDirectoryString[] = "\\";
79
- // Windows CE doesn't define INVALID_FILE_ATTRIBUTES
80
- const DWORD kInvalidFileAttributes = 0xffffffff;
81
- # else
82
- const char kCurrentDirectoryString[] = ".\\";
83
- # endif // GTEST_OS_WINDOWS_MOBILE
84
- #else
85
- const char kPathSeparator = '/';
86
- const char kPathSeparatorString[] = "/";
87
- const char kCurrentDirectoryString[] = "./";
88
- #endif // GTEST_OS_WINDOWS
89
-
90
- // Returns whether the given character is a valid path separator.
91
- static bool IsPathSeparator(char c) {
92
- #if GTEST_HAS_ALT_PATH_SEP_
93
- return (c == kPathSeparator) || (c == kAlternatePathSeparator);
94
- #else
95
- return c == kPathSeparator;
96
- #endif
97
- }
98
-
99
- // Returns the current working directory, or "" if unsuccessful.
100
- FilePath FilePath::GetCurrentDir() {
101
- #if GTEST_OS_WINDOWS_MOBILE
102
- // Windows CE doesn't have a current directory, so we just return
103
- // something reasonable.
104
- return FilePath(kCurrentDirectoryString);
105
- #elif GTEST_OS_WINDOWS
106
- char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
107
- return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
108
- #else
109
- char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
110
- return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
111
- #endif // GTEST_OS_WINDOWS_MOBILE
112
- }
113
-
114
- // Returns a copy of the FilePath with the case-insensitive extension removed.
115
- // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
116
- // FilePath("dir/file"). If a case-insensitive extension is not
117
- // found, returns a copy of the original FilePath.
118
- FilePath FilePath::RemoveExtension(const char* extension) const {
119
- String dot_extension(String::Format(".%s", extension));
120
- if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) {
121
- return FilePath(String(pathname_.c_str(), pathname_.length() - 4));
122
- }
123
- return *this;
124
- }
125
-
126
- // Returns a pointer to the last occurence of a valid path separator in
127
- // the FilePath. On Windows, for example, both '/' and '\' are valid path
128
- // separators. Returns NULL if no path separator was found.
129
- const char* FilePath::FindLastPathSeparator() const {
130
- const char* const last_sep = strrchr(c_str(), kPathSeparator);
131
- #if GTEST_HAS_ALT_PATH_SEP_
132
- const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
133
- // Comparing two pointers of which only one is NULL is undefined.
134
- if (last_alt_sep != NULL &&
135
- (last_sep == NULL || last_alt_sep > last_sep)) {
136
- return last_alt_sep;
137
- }
138
- #endif
139
- return last_sep;
140
- }
141
-
142
- // Returns a copy of the FilePath with the directory part removed.
143
- // Example: FilePath("path/to/file").RemoveDirectoryName() returns
144
- // FilePath("file"). If there is no directory part ("just_a_file"), it returns
145
- // the FilePath unmodified. If there is no file part ("just_a_dir/") it
146
- // returns an empty FilePath ("").
147
- // On Windows platform, '\' is the path separator, otherwise it is '/'.
148
- FilePath FilePath::RemoveDirectoryName() const {
149
- const char* const last_sep = FindLastPathSeparator();
150
- return last_sep ? FilePath(String(last_sep + 1)) : *this;
151
- }
152
-
153
- // RemoveFileName returns the directory path with the filename removed.
154
- // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
155
- // If the FilePath is "a_file" or "/a_file", RemoveFileName returns
156
- // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
157
- // not have a file, like "just/a/dir/", it returns the FilePath unmodified.
158
- // On Windows platform, '\' is the path separator, otherwise it is '/'.
159
- FilePath FilePath::RemoveFileName() const {
160
- const char* const last_sep = FindLastPathSeparator();
161
- String dir;
162
- if (last_sep) {
163
- dir = String(c_str(), last_sep + 1 - c_str());
164
- } else {
165
- dir = kCurrentDirectoryString;
166
- }
167
- return FilePath(dir);
168
- }
169
-
170
- // Helper functions for naming files in a directory for xml output.
171
-
172
- // Given directory = "dir", base_name = "test", number = 0,
173
- // extension = "xml", returns "dir/test.xml". If number is greater
174
- // than zero (e.g., 12), returns "dir/test_12.xml".
175
- // On Windows platform, uses \ as the separator rather than /.
176
- FilePath FilePath::MakeFileName(const FilePath& directory,
177
- const FilePath& base_name,
178
- int number,
179
- const char* extension) {
180
- String file;
181
- if (number == 0) {
182
- file = String::Format("%s.%s", base_name.c_str(), extension);
183
- } else {
184
- file = String::Format("%s_%d.%s", base_name.c_str(), number, extension);
185
- }
186
- return ConcatPaths(directory, FilePath(file));
187
- }
188
-
189
- // Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
190
- // On Windows, uses \ as the separator rather than /.
191
- FilePath FilePath::ConcatPaths(const FilePath& directory,
192
- const FilePath& relative_path) {
193
- if (directory.IsEmpty())
194
- return relative_path;
195
- const FilePath dir(directory.RemoveTrailingPathSeparator());
196
- return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator,
197
- relative_path.c_str()));
198
- }
199
-
200
- // Returns true if pathname describes something findable in the file-system,
201
- // either a file, directory, or whatever.
202
- bool FilePath::FileOrDirectoryExists() const {
203
- #if GTEST_OS_WINDOWS_MOBILE
204
- LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
205
- const DWORD attributes = GetFileAttributes(unicode);
206
- delete [] unicode;
207
- return attributes != kInvalidFileAttributes;
208
- #else
209
- posix::StatStruct file_stat;
210
- return posix::Stat(pathname_.c_str(), &file_stat) == 0;
211
- #endif // GTEST_OS_WINDOWS_MOBILE
212
- }
213
-
214
- // Returns true if pathname describes a directory in the file-system
215
- // that exists.
216
- bool FilePath::DirectoryExists() const {
217
- bool result = false;
218
- #if GTEST_OS_WINDOWS
219
- // Don't strip off trailing separator if path is a root directory on
220
- // Windows (like "C:\\").
221
- const FilePath& path(IsRootDirectory() ? *this :
222
- RemoveTrailingPathSeparator());
223
- #else
224
- const FilePath& path(*this);
225
- #endif
226
-
227
- #if GTEST_OS_WINDOWS_MOBILE
228
- LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
229
- const DWORD attributes = GetFileAttributes(unicode);
230
- delete [] unicode;
231
- if ((attributes != kInvalidFileAttributes) &&
232
- (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
233
- result = true;
234
- }
235
- #else
236
- posix::StatStruct file_stat;
237
- result = posix::Stat(path.c_str(), &file_stat) == 0 &&
238
- posix::IsDir(file_stat);
239
- #endif // GTEST_OS_WINDOWS_MOBILE
240
-
241
- return result;
242
- }
243
-
244
- // Returns true if pathname describes a root directory. (Windows has one
245
- // root directory per disk drive.)
246
- bool FilePath::IsRootDirectory() const {
247
- #if GTEST_OS_WINDOWS
248
- // TODO(wan@google.com): on Windows a network share like
249
- // \\server\share can be a root directory, although it cannot be the
250
- // current directory. Handle this properly.
251
- return pathname_.length() == 3 && IsAbsolutePath();
252
- #else
253
- return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
254
- #endif
255
- }
256
-
257
- // Returns true if pathname describes an absolute path.
258
- bool FilePath::IsAbsolutePath() const {
259
- const char* const name = pathname_.c_str();
260
- #if GTEST_OS_WINDOWS
261
- return pathname_.length() >= 3 &&
262
- ((name[0] >= 'a' && name[0] <= 'z') ||
263
- (name[0] >= 'A' && name[0] <= 'Z')) &&
264
- name[1] == ':' &&
265
- IsPathSeparator(name[2]);
266
- #else
267
- return IsPathSeparator(name[0]);
268
- #endif
269
- }
270
-
271
- // Returns a pathname for a file that does not currently exist. The pathname
272
- // will be directory/base_name.extension or
273
- // directory/base_name_<number>.extension if directory/base_name.extension
274
- // already exists. The number will be incremented until a pathname is found
275
- // that does not already exist.
276
- // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
277
- // There could be a race condition if two or more processes are calling this
278
- // function at the same time -- they could both pick the same filename.
279
- FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
280
- const FilePath& base_name,
281
- const char* extension) {
282
- FilePath full_pathname;
283
- int number = 0;
284
- do {
285
- full_pathname.Set(MakeFileName(directory, base_name, number++, extension));
286
- } while (full_pathname.FileOrDirectoryExists());
287
- return full_pathname;
288
- }
289
-
290
- // Returns true if FilePath ends with a path separator, which indicates that
291
- // it is intended to represent a directory. Returns false otherwise.
292
- // This does NOT check that a directory (or file) actually exists.
293
- bool FilePath::IsDirectory() const {
294
- return !pathname_.empty() &&
295
- IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
296
- }
297
-
298
- // Create directories so that path exists. Returns true if successful or if
299
- // the directories already exist; returns false if unable to create directories
300
- // for any reason.
301
- bool FilePath::CreateDirectoriesRecursively() const {
302
- if (!this->IsDirectory()) {
303
- return false;
304
- }
305
-
306
- if (pathname_.length() == 0 || this->DirectoryExists()) {
307
- return true;
308
- }
309
-
310
- const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());
311
- return parent.CreateDirectoriesRecursively() && this->CreateFolder();
312
- }
313
-
314
- // Create the directory so that path exists. Returns true if successful or
315
- // if the directory already exists; returns false if unable to create the
316
- // directory for any reason, including if the parent directory does not
317
- // exist. Not named "CreateDirectory" because that's a macro on Windows.
318
- bool FilePath::CreateFolder() const {
319
- #if GTEST_OS_WINDOWS_MOBILE
320
- FilePath removed_sep(this->RemoveTrailingPathSeparator());
321
- LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
322
- int result = CreateDirectory(unicode, NULL) ? 0 : -1;
323
- delete [] unicode;
324
- #elif GTEST_OS_WINDOWS
325
- int result = _mkdir(pathname_.c_str());
326
- #else
327
- int result = mkdir(pathname_.c_str(), 0777);
328
- #endif // GTEST_OS_WINDOWS_MOBILE
329
-
330
- if (result == -1) {
331
- return this->DirectoryExists(); // An error is OK if the directory exists.
332
- }
333
- return true; // No error.
334
- }
335
-
336
- // If input name has a trailing separator character, remove it and return the
337
- // name, otherwise return the name string unmodified.
338
- // On Windows platform, uses \ as the separator, other platforms use /.
339
- FilePath FilePath::RemoveTrailingPathSeparator() const {
340
- return IsDirectory()
341
- ? FilePath(String(pathname_.c_str(), pathname_.length() - 1))
342
- : *this;
343
- }
344
-
345
- // Removes any redundant separators that might be in the pathname.
346
- // For example, "bar///foo" becomes "bar/foo". Does not eliminate other
347
- // redundancies that might be in a pathname involving "." or "..".
348
- // TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
349
- void FilePath::Normalize() {
350
- if (pathname_.c_str() == NULL) {
351
- pathname_ = "";
352
- return;
353
- }
354
- const char* src = pathname_.c_str();
355
- char* const dest = new char[pathname_.length() + 1];
356
- char* dest_ptr = dest;
357
- memset(dest_ptr, 0, pathname_.length() + 1);
358
-
359
- while (*src != '\0') {
360
- *dest_ptr = *src;
361
- if (!IsPathSeparator(*src)) {
362
- src++;
363
- } else {
364
- #if GTEST_HAS_ALT_PATH_SEP_
365
- if (*dest_ptr == kAlternatePathSeparator) {
366
- *dest_ptr = kPathSeparator;
367
- }
368
- #endif
369
- while (IsPathSeparator(*src))
370
- src++;
371
- }
372
- dest_ptr++;
373
- }
374
- *dest_ptr = '\0';
375
- pathname_ = dest;
376
- delete[] dest;
377
- }
378
-
379
- } // namespace internal
380
- } // namespace testing