Skip to content

Commit 3352878

Browse files
committed
inc
1 parent 3833745 commit 3352878

3 files changed

Lines changed: 38 additions & 17 deletions

File tree

lib/path.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,20 @@
3232
#include <unistd.h>
3333
#else
3434
#include <direct.h>
35+
#include <stdexcept>
3536
#endif
3637
#if defined(__CYGWIN__)
3738
#include <strings.h>
3839
#endif
3940

4041
#include <simplecpp.h>
4142

43+
#if defined(_WIN32) && !defined(__MINGW32__)
44+
static const char SEP_NATIVE = '\\';
45+
#else
46+
static const char SEP_NATIVE = '/';
47+
#endif
48+
4249
/** Is the filesystem case insensitive? */
4350
static bool caseInsensitiveFilesystem()
4451
{
@@ -54,20 +61,16 @@ std::string Path::toNativeSeparators(std::string path)
5461
{
5562
#if defined(_WIN32)
5663
const char separ = '/';
57-
const char native = '\\';
5864
#else
5965
const char separ = '\\';
60-
const char native = '/';
6166
#endif
62-
std::replace(path.begin(), path.end(), separ, native);
67+
std::replace(path.begin(), path.end(), separ, SEP_NATIVE);
6368
return path;
6469
}
6570

6671
std::string Path::fromNativeSeparators(std::string path)
6772
{
68-
const char nonnative = '\\';
69-
const char newsepar = '/';
70-
std::replace(path.begin(), path.end(), nonnative, newsepar);
73+
std::replace(path.begin(), path.end(), '\\', '/');
7174
return path;
7275
}
7376

@@ -211,9 +214,13 @@ std::string Path::getAbsoluteFilePath(const std::string& filePath)
211214
if (_fullpath(absolute, filePath.c_str(), _MAX_PATH))
212215
absolute_path = absolute;
213216
#elif defined(__linux__) || defined(__sun) || defined(__hpux) || defined(__GNUC__) || defined(__CPPCHECK__)
217+
// realpath() only works with files that actually exist
214218
char * absolute = realpath(filePath.c_str(), nullptr);
215-
if (absolute)
216-
absolute_path = absolute;
219+
if (!absolute) {
220+
const int err = errno;
221+
throw std::runtime_error("realpath() failed with " + std::to_string(err));
222+
}
223+
absolute_path = absolute;
217224
free(absolute);
218225
#else
219226
#error Platform absolute path function needed
@@ -223,13 +230,7 @@ std::string Path::getAbsoluteFilePath(const std::string& filePath)
223230

224231
std::string Path::stripDirectoryPart(const std::string &file)
225232
{
226-
#if defined(_WIN32) && !defined(__MINGW32__)
227-
const char native = '\\';
228-
#else
229-
const char native = '/';
230-
#endif
231-
232-
const std::string::size_type p = file.rfind(native);
233+
const std::string::size_type p = file.rfind(SEP_NATIVE);
233234
if (p != std::string::npos) {
234235
return file.substr(p + 1);
235236
}
@@ -243,6 +244,8 @@ bool Path::fileExists(const std::string &file)
243244
}
244245

245246
std::string Path::join(std::string path1, std::string path2) {
247+
path1 = fromNativeSeparators(std::move(path1));
248+
path2 = fromNativeSeparators(std::move(path2));
246249
if (path1.empty() || path2.empty())
247250
return path1 + path2;
248251
if (path2.front() == '/')

test/helpers.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ ScopedFile::ScopedFile(std::string name, const std::string &content, std::string
4444
throw std::runtime_error("ScopedFile(" + mFullPath + ") - could not create directory");
4545
#endif
4646
}
47-
std::cout << mName << " - " << mPath << " - " << mFullPath << " - " << Path::getAbsoluteFilePath(mFullPath) << std::endl;
4847

49-
std::ofstream of(Path::getAbsoluteFilePath(mFullPath));
48+
std::cout << Path::getCurrentPath() << std::endl;
49+
50+
std::ofstream of(mFullPath);
5051
if (!of.is_open())
5152
throw std::runtime_error("ScopedFile(" + mFullPath + ") - could not open file");
5253
of << content;

test/testpath.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class TestPath : public TestFixture {
3838
TEST_CASE(is_cpp);
3939
TEST_CASE(get_path_from_filename);
4040
TEST_CASE(join);
41+
TEST_CASE(getAbsoluteFilePath);
4142
}
4243

4344
void removeQuotationMarks() const {
@@ -148,7 +149,23 @@ class TestPath : public TestFixture {
148149
ASSERT_EQUALS("a", Path::join("", "a"));
149150
ASSERT_EQUALS("a/b", Path::join("a", "b"));
150151
ASSERT_EQUALS("a/b", Path::join("a/", "b"));
152+
ASSERT_EQUALS("a/b", Path::join("a\\", "b"));
151153
ASSERT_EQUALS("/b", Path::join("a", "/b"));
154+
ASSERT_EQUALS("/b", Path::join("a", "\\b"));
155+
}
156+
157+
// TODO: this is quite messy - should Path::getAbsoluteFilePath() return normalized separators?
158+
void getAbsoluteFilePath() const {
159+
// Path::getAbsoluteFilePath() only works with existing paths on Linux
160+
#ifdef _WIN32
161+
const std::string cwd = Path::getCurrentPath();
162+
ASSERT_EQUALS(Path::join(cwd, "a.h"), Path::fromNativeSeparators(Path::getAbsoluteFilePath("a.h")));
163+
ASSERT_EQUALS(Path::join(cwd, "inc/a.h"), Path::fromNativeSeparators(Path::getAbsoluteFilePath("inc/a.h")));
164+
const std::string cwd_down = Path::getPathFromFilename(cwd);
165+
ASSERT_EQUALS(Path::join(cwd_down, "a.h"), Path::fromNativeSeparators(Path::getAbsoluteFilePath("../a.h")));
166+
ASSERT_EQUALS(Path::join(cwd_down, "inc/a.h"), Path::fromNativeSeparators(Path::getAbsoluteFilePath("../inc/a.h")));
167+
ASSERT_EQUALS(Path::join(cwd_down, "inc/a.h"), Path::fromNativeSeparators(Path::getAbsoluteFilePath("../inc/../inc/a.h")));
168+
#endif
152169
}
153170
};
154171

0 commit comments

Comments
 (0)