Skip to content

Commit

Permalink
Updated ecal_utils to fix compile issue
Browse files Browse the repository at this point in the history
  • Loading branch information
FlorianReimold committed Feb 18, 2021
1 parent 171a76b commit 10cea11
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 21 deletions.
10 changes: 8 additions & 2 deletions lib/ecal_utils/include/ecal_utils/filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#pragma once

#include <string>
#include <list>
#include <vector>
#include <map>

#include <sys/stat.h>
Expand Down Expand Up @@ -107,11 +107,13 @@ namespace EcalUtils
bool IsRelative(const std::string& path, OsStyle input_path_style = OsStyle::Combined);

std::string CleanPath(const std::string& path, OsStyle input_path_style = OsStyle::Combined);
std::list<std::string> CleanPathComponentList(const std::string& path, OsStyle input_path_style = OsStyle::Combined);
std::vector<std::string> CleanPathComponentList(const std::string& path, OsStyle input_path_style = OsStyle::Combined);

std::string AbsolutePath(const std::string& base_path, const std::string& relative_path, OsStyle input_path_style = OsStyle::Combined);
std::string AbsolutePath(const std::string& relative_path, OsStyle input_path_style = OsStyle::Combined);

std::string RelativePath(const std::string& base_path, const std::string& path, OsStyle input_path_style = OsStyle::Combined);

std::string CurrentWorkingDir();
std::string ApplicationDir();

Expand All @@ -132,5 +134,9 @@ namespace EcalUtils
}

bool IsEqual(const std::string& path1, const std::string& path2, OsStyle compare_for = OsStyle::Current);

std::string FileName(const std::string& path, OsStyle input_path_style = OsStyle::Combined);

std::string BaseName(const std::string& path, OsStyle input_path_style = OsStyle::Combined);
};
}
128 changes: 109 additions & 19 deletions lib/ecal_utils/src/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@
#else // _WIN32
#include <dirent.h>
#include <fcntl.h> // O_RDONLY
#include <fts.h> // File-tree traversal
#ifndef __QNXNTO__
#include <fts.h> // File-tree traversal
#endif
#include <unistd.h>

#if defined (__APPLE__) || defined(__FreeBSD__)
#include <copyfile.h>
#else
#include <sys/sendfile.h>
#ifndef __QNXNTO__
#include <sys/sendfile.h>
#endif
#endif //__linux__

#endif // _WIN32
Expand Down Expand Up @@ -310,6 +314,9 @@ namespace EcalUtils
#if defined (__APPLE__) || defined(__FreeBSD__)
int result = fcopyfile(input_fd, output_fd, 0, COPYFILE_ALL);
return (result == 0);
#elif defined(__QNXNTO__)
// TODO: Find an alternative to copy files on QNX operating system
return false;
#else
off_t bytesCopied = 0;
FileStatus file_status(source_clean, OsStyle::Current);
Expand All @@ -323,7 +330,7 @@ namespace EcalUtils
{
std::string clean_path = ToNativeSeperators(CleanPath(source, input_path_style), input_path_style);

#ifdef WIN32
#if defined(WIN32)

// Abuse the internal buffer of the string to make a double-null-
// terminated-string as requested by the Win32 API.
Expand All @@ -345,7 +352,10 @@ namespace EcalUtils
};
int error = SHFileOperationA(&file_op);
return (error == 0);


#elif defined(__QNXNTO__)
// TODO: Find an alternative to traverse directories on QNX operating system that does not use fts
return false;
#else // WIN32

// This code has been taken from the open-bsd rm sourcecode:
Expand Down Expand Up @@ -499,14 +509,14 @@ namespace EcalUtils
}
}

std::list<std::string> CleanPathComponentList(const std::string& path, OsStyle input_path_style)
std::vector<std::string> CleanPathComponentList(const std::string& path, OsStyle input_path_style)
{
if (path.empty())
{
return{};
}

std::list<std::string> components;
std::vector<std::string> components;

std::string unix_style_path = ToUnixSeperators(path, input_path_style);

Expand All @@ -522,13 +532,18 @@ namespace EcalUtils
EcalUtils::String::Split(unix_style_path, "/", splitted_path);

// The components-stack that will increase and shrink depending on the folders and .. elements in the splitted path
for (const std::string& part : splitted_path)
for (auto part_it = splitted_path.begin(); part_it != splitted_path.end(); part_it++)
{
if (part.empty() || part == ".")
if ((part_it == splitted_path.begin()) && (*part_it == ".") && !is_absolute)
{
// Preserve a leading ".", if the path is relative. It may indicate the working director, so we should not skip it.
components.push_back(".");
}
else if (part_it->empty() || *part_it == ".")
{
continue;
}
else if (part == "..")
else if (*part_it == "..")
{
if (is_absolute)
{
Expand All @@ -553,24 +568,23 @@ namespace EcalUtils
}
else
{
components.push_back(part);
components.push_back(*part_it);
}
}

return components;
}


std::string CleanPath(const std::string& path, OsStyle input_path_style)
{
if (path.empty())
return ".";
return "";

// Split the path into its cleaned components
std::list<std::string> cleaned_path_components = CleanPathComponentList(path, input_path_style);
std::vector<std::string> cleaned_path_components = CleanPathComponentList(path, input_path_style);

// Check whether the path ended with a slash
bool tailing_separator = ((path.back() == '/') || (path.back() == '\\'));
bool tailing_separator = (ToUnixSeperators(path, input_path_style).back() == '/');

// Gather information about the root (it will not be in the components list)
std::string root = GetAbsoluteRoot(path, input_path_style);
Expand All @@ -590,11 +604,11 @@ namespace EcalUtils
}
else
{
cleaned_path += '.';
if (!cleaned_path_components.empty())
{
cleaned_path += '/';
}
//cleaned_path += '.';
//if (!cleaned_path_components.empty())
//{
// cleaned_path += '/';
//}
}

cleaned_path += EcalUtils::String::Join("/", cleaned_path_components);
Expand Down Expand Up @@ -624,6 +638,43 @@ namespace EcalUtils
}
}

std::string RelativePath(const std::string& base_path, const std::string& path, OsStyle input_path_style)
{
auto base_list = CleanPathComponentList(base_path, input_path_style);
auto path_list = CleanPathComponentList(path, input_path_style);

size_t size = (path_list.size() < base_list.size()) ? path_list.size() : base_list.size();
unsigned int same_size(0);
for (unsigned int i = 0; i < size; ++i)
{
if (path_list[i] != base_list[i])
{
same_size = i;
break;
}
}

std::string relative_path = "";
if (same_size > 0)
{
for (unsigned int i = 0; i < base_list.size() - same_size; ++i)
{
relative_path += "../";
}
}

for (unsigned int i = same_size; i < path_list.size(); ++i)
{
relative_path += path_list[i];
if (i < path_list.size() - 1)
{
relative_path += "/";
}
}

return relative_path;
}

std::string CurrentWorkingDir()
{
#ifdef _WIN32
Expand Down Expand Up @@ -745,5 +796,44 @@ namespace EcalUtils

return true;
}

std::string FileName(const std::string& path, OsStyle input_path_style)
{
if (path.empty())
return "";

if (path.back() == '/')
return "";

if ((input_path_style == OsStyle::Windows) || (input_path_style == OsStyle::Combined))
{
if (path.back() == '\\')
return "";
}

auto clean_path_component_list = CleanPathComponentList(path, input_path_style);

if (clean_path_component_list.empty())
return "";
else
return clean_path_component_list.back();
}

std::string BaseName(const std::string& path, OsStyle input_path_style)
{
std::string file_name = FileName(path, input_path_style);

if (file_name.empty()) return "";

size_t pos = file_name.find('.', 0);
if (pos != std::string::npos)
{
return file_name.substr(0, pos);
}
else
{
return file_name;
}
}
}
}

0 comments on commit 10cea11

Please sign in to comment.