-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathInstallationDirectories.cc
162 lines (142 loc) · 4.57 KB
/
InstallationDirectories.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
* Copyright (C) 2023 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <regex>
#include <gz/physics/config.hh>
#include <gz/physics/InstallationDirectories.hh>
#ifdef _WIN32
#include <shlwapi.h>
#endif
namespace gz
{
namespace physics
{
namespace {
// We locally import the gz::common::joinPaths function
// See https://github.com/gazebosim/gz-physics/pull/507#discussion_r1186919267
// for more details
// Function imported from
// https://github.com/gazebosim/gz-common/blob/ignition-common4_4.6.2/src/FilesystemBoost.cc#L507
#ifndef _WIN32
const char preferred_separator = '/';
#else // Windows
static const char preferred_separator = '\\';
#endif
std::string separator(const std::string &_p)
{
return _p + preferred_separator;
}
#ifdef _WIN32
// Function imported from
// https://github.com/gazebosim/gz-common/blob/ignition-common4_4.6.2/src/Filesystem.cc#L227
std::string checkWindowsPath(const std::string &_path)
{
if (_path.empty())
return _path;
// Check if this is a http or https, if so change backslashes generated by
// jointPaths to '/'
if ((_path.size() > 7 && 0 == _path.compare(0, 7, "http://")) ||
(_path.size() > 8 && 0 == _path.compare(0, 8, "https://")))
{
return std::regex_replace(_path, std::regex(R"(\\)"), "/");
}
// This is a Windows path, convert all '/' into backslashes
std::string result = std::regex_replace(_path, std::regex(R"(/)"), "\\");
std::string drive_letters;
// only Windows contains absolute paths starting with drive letters
if (result.length() > 3 && 0 == result.compare(1, 2, ":\\"))
{
drive_letters = result.substr(0, 3);
result = result.substr(3);
}
result = drive_letters + std::regex_replace(
result, std::regex("[<>:\"|?*]"), "");
return result;
}
#endif
// Function imported from
// https://github.com/gazebosim/gz-common/blob/ignition-common4_4.6.2/src/Filesystem.cc#L256
std::string joinPaths(const std::string &_path1,
const std::string &_path2)
{
/// This function is used to avoid duplicated path separators at the
/// beginning/end of the string, and between the two paths being joined.
/// \param[in] _path This is the string to sanitize.
/// \param[in] _stripLeading True if the leading separator should be
/// removed.
auto sanitizeSlashes = [](const std::string &_path,
bool _stripLeading = false)
{
// Shortcut
if (_path.empty())
return _path;
std::string result = _path;
// Use the appropriate character for each platform.
#ifndef _WIN32
char replacement = '/';
#else
char replacement = '\\';
#endif // _WIN32
// Sanitize the start of the path.
size_t index = 0;
size_t leadingIndex = _stripLeading ? 0 : 1;
for (; index < result.length() && result[index] == replacement; ++index)
{
}
if (index > leadingIndex)
result.erase(leadingIndex, index-leadingIndex);
// Sanitize the end of the path.
index = result.length()-1;
for (; index < result.length() && result[index] == replacement; --index)
{
}
index += 1;
if (index < result.length()-1)
result.erase(index+1);
return result;
};
std::string path;
#ifndef _WIN32
path = sanitizeSlashes(sanitizeSlashes(separator(_path1)) +
sanitizeSlashes(_path2, true));
#else // _WIN32
std::string path1 = sanitizeSlashes(checkWindowsPath(_path1));
std::string path2 = sanitizeSlashes(checkWindowsPath(_path2), true);
std::vector<char> combined(path1.length() + path2.length() + 2);
if (::PathCombineA(combined.data(), path1.c_str(), path2.c_str()) != NULL)
{
path = sanitizeSlashes(checkWindowsPath(std::string(combined.data())));
}
else
{
path = sanitizeSlashes(checkWindowsPath(separator(path1) + path2));
}
#endif // _WIN32
return path;
}
}
inline namespace GZ_PHYSICS_VERSION_NAMESPACE {
#ifdef GZ_PHYSICS_BAZEL_BUILD
std::string getInstallPrefix() { return "physics"; }
#endif
std::string getEngineInstallDir()
{
return gz::physics::joinPaths(
getInstallPrefix(), GZ_PHYSICS_ENGINE_RELATIVE_INSTALL_DIR);
}
}
}
}