| 303 | } |
| 304 | |
| 305 | BOOST_FILESYSTEM_DECL path path_algorithms::lexically_normal_v4(path const& p) |
| 306 | { |
| 307 | const value_type* const pathname = p.m_pathname.c_str(); |
| 308 | const size_type pathname_size = p.m_pathname.size(); |
| 309 | size_type root_name_size = 0; |
| 310 | size_type root_dir_pos = find_root_directory_start(pathname, pathname_size, root_name_size); |
| 311 | path normal(pathname, pathname + root_name_size); |
| 312 | |
| 313 | size_type root_path_size = root_name_size; |
| 314 | if (root_dir_pos < pathname_size) |
| 315 | { |
| 316 | root_path_size = root_dir_pos + 1; |
| 317 | normal.m_pathname.push_back(path::preferred_separator); |
| 318 | } |
| 319 | |
| 320 | size_type i = root_path_size; |
| 321 | |
| 322 | // Skip redundant directory separators after the root directory |
| 323 | while (i < pathname_size && detail::is_directory_separator(pathname[i])) |
| 324 | ++i; |
| 325 | |
| 326 | if (i < pathname_size) |
| 327 | { |
| 328 | while (true) |
| 329 | { |
| 330 | bool last_element_was_dot = false; |
| 331 | { |
| 332 | const size_type start_pos = i; |
| 333 | |
| 334 | // Find next separator |
| 335 | i += find_separator(pathname + i, pathname_size - i); |
| 336 | |
| 337 | const size_type size = i - start_pos; |
| 338 | |
| 339 | // Skip dot elements |
| 340 | if (size == 1u && pathname[start_pos] == path::dot) |
| 341 | { |
| 342 | last_element_was_dot = true; |
| 343 | goto skip_append; |
| 344 | } |
| 345 | |
| 346 | // Process dot dot elements |
| 347 | if (size == 2u && pathname[start_pos] == path::dot && pathname[start_pos + 1] == path::dot && normal.m_pathname.size() > root_path_size) |
| 348 | { |
| 349 | // Don't remove previous dot dot elements |
| 350 | const size_type normal_size = normal.m_pathname.size(); |
| 351 | size_type filename_size = find_filename_size(normal.m_pathname, root_path_size, normal_size); |
| 352 | size_type pos = normal_size - filename_size; |
| 353 | if (filename_size != 2u || normal.m_pathname[pos] != path::dot || normal.m_pathname[pos + 1] != path::dot) |
| 354 | { |
| 355 | if (pos > root_path_size && detail::is_directory_separator(normal.m_pathname[pos - 1])) |
| 356 | --pos; |
| 357 | normal.m_pathname.erase(normal.m_pathname.begin() + pos, normal.m_pathname.end()); |
| 358 | goto skip_append; |
| 359 | } |
| 360 | } |
| 361 | |
| 362 | // Append the element |
nothing calls this directly
no test coverage detected