| 257 | } |
| 258 | |
| 259 | bool FilePath::AppendRelativePath(const FilePath& child, |
| 260 | FilePath* path) const { |
| 261 | std::vector<StringType> parent_components; |
| 262 | std::vector<StringType> child_components; |
| 263 | GetComponents(&parent_components); |
| 264 | child.GetComponents(&child_components); |
| 265 | |
| 266 | if (parent_components.empty() || |
| 267 | parent_components.size() >= child_components.size()) |
| 268 | return false; |
| 269 | |
| 270 | std::vector<StringType>::const_iterator parent_comp = |
| 271 | parent_components.begin(); |
| 272 | std::vector<StringType>::const_iterator child_comp = |
| 273 | child_components.begin(); |
| 274 | |
| 275 | #if defined(FILE_PATH_USES_DRIVE_LETTERS) |
| 276 | // Windows can access case sensitive filesystems, so component |
| 277 | // comparisions must be case sensitive, but drive letters are |
| 278 | // never case sensitive. |
| 279 | if ((FindDriveLetter(*parent_comp) != StringType::npos) && |
| 280 | (FindDriveLetter(*child_comp) != StringType::npos)) { |
| 281 | if (!StartsWith(*parent_comp, *child_comp, false)) |
| 282 | return false; |
| 283 | ++parent_comp; |
| 284 | ++child_comp; |
| 285 | } |
| 286 | #endif // defined(FILE_PATH_USES_DRIVE_LETTERS) |
| 287 | |
| 288 | while (parent_comp != parent_components.end()) { |
| 289 | if (*parent_comp != *child_comp) |
| 290 | return false; |
| 291 | ++parent_comp; |
| 292 | ++child_comp; |
| 293 | } |
| 294 | |
| 295 | if (path != NULL) { |
| 296 | for (; child_comp != child_components.end(); ++child_comp) { |
| 297 | *path = path->Append(*child_comp); |
| 298 | } |
| 299 | } |
| 300 | return true; |
| 301 | } |
| 302 | |
| 303 | // libgen's dirname and basename aren't guaranteed to be thread-safe and aren't |
| 304 | // guaranteed to not modify their input strings, and in fact are implemented |
no test coverage detected