Skip to content

Commit

Permalink
add test on XmlInputSource; refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
ctapmex committed Oct 16, 2024
1 parent 7a0caca commit a648b9d
Show file tree
Hide file tree
Showing 11 changed files with 239 additions and 48 deletions.
2 changes: 1 addition & 1 deletion src/colorer/parsers/ParserFactoryImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void ParserFactory::Impl::loadHrcPath(const UnicodeString& location)
{
try {
COLORER_LOG_DEBUG("try load '%'", location);
if (XmlInputSource::isFileURI(*base_catalog_path, &location)) {
if (XmlInputSource::isFsURI(*base_catalog_path, &location)) {
auto files = colorer::Environment::getFilesFromPath(base_catalog_path.get(), &location, ".hrc");
for (auto& file : files) {
loadHrc(file, nullptr);
Expand Down
87 changes: 54 additions & 33 deletions src/colorer/utils/Environment.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#include "colorer/utils/Environment.h"
#include <regex>
#ifdef WIN32
#include <windows.h>
#include <cwchar>
#endif

namespace colorer {

fs::path Environment::to_filepath(const UnicodeString* str)
{
#ifdef _WINDOWS
Expand All @@ -18,7 +18,7 @@ fs::path Environment::to_filepath(const UnicodeString* str)

uUnicodeString Environment::getOSVariable(const UnicodeString& name)
{
#ifdef WIN32
#ifdef _WINDOWS
COLORER_LOG_DEBUG("get system environment '%'", name);
auto str_name = UStr::to_stdwstr(&name);
size_t sz = 0;
Expand All @@ -44,36 +44,9 @@ uUnicodeString Environment::getOSVariable(const UnicodeString& name)
COLORER_LOG_DEBUG("'%' not set", name);
return nullptr;
}
else {
COLORER_LOG_DEBUG("'%' = '%'", name, value);
return std::make_unique<UnicodeString>(value);
}
#endif
}

uUnicodeString Environment::expandEnvironment(const UnicodeString* path)
{
COLORER_LOG_DEBUG("expand system environment for '%'", *path);
#ifdef WIN32
std::wstring path_ws = UStr::to_stdwstr(path);
size_t i = ExpandEnvironmentStringsW(path_ws.c_str(), nullptr, 0);
auto temp = std::make_unique<wchar_t[]>(i);
ExpandEnvironmentStringsW(path_ws.c_str(), temp.get(), static_cast<DWORD>(i));
return std::make_unique<UnicodeString>(temp.get());
#else
std::smatch matcher;
std::string result;
auto text = UStr::to_stdstr(path);
static const std::regex env_re {R"--(\$\{([^}]+)\})--"};
while (std::regex_search(text, matcher, env_re)) {
result += matcher.prefix().str();
result += std::getenv(matcher[1].str().c_str());
text = matcher.suffix().str();
}
result += text;

COLORER_LOG_DEBUG("result of expand '%'", result);
return std::make_unique<UnicodeString>(result.c_str());
COLORER_LOG_DEBUG("'%' = '%'", name, value);
return std::make_unique<UnicodeString>(value);
#endif
}

Expand All @@ -84,8 +57,8 @@ uUnicodeString Environment::normalizePath(const UnicodeString* path)

fs::path Environment::normalizeFsPath(const UnicodeString* path)
{
auto expanded_string = Environment::expandEnvironment(path);
auto fpath = fs::path(Environment::to_filepath(expanded_string.get()));
auto expanded_string = expandEnvironment(*path);
auto fpath = fs::path(to_filepath(&expanded_string));
fpath = fpath.lexically_normal();
if (fs::is_symlink(fpath)) {
fpath = fs::read_symlink(fpath);
Expand Down Expand Up @@ -178,4 +151,52 @@ UnicodeString Environment::expandSpecialEnvironment(const UnicodeString& path)
COLORER_LOG_DEBUG("result of expand '%'", result);
return UnicodeString(result.c_str());
}

UnicodeString Environment::expandEnvironment(const UnicodeString& path)
{
COLORER_LOG_DEBUG("expand system environment for '%'", path);
if (path.isEmpty()) {
COLORER_LOG_DEBUG("result of expand ''");
return {};
}

#ifdef _WINDOWS
std::wstring path_ws = UStr::to_stdwstr(&path);
size_t i = ExpandEnvironmentStringsW(path_ws.c_str(), nullptr, 0);
auto temp = std::make_unique<wchar_t[]>(i);
ExpandEnvironmentStringsW(path_ws.c_str(), temp.get(), static_cast<DWORD>(i));
COLORER_LOG_DEBUG("result of expand '%'", temp.get());
return {temp.get()};
#else
const auto text = UStr::to_stdstr(&path);
auto res = expandEnvByRegexp(text, std::regex(R"--(\$\{([[:alpha:]]\w*)\})--"));
res = expandEnvByRegexp(res, std::regex(R"--(\$([[:alpha:]]\w*)\b)--"));
COLORER_LOG_DEBUG("result of expand '%'", res);
return {res.c_str()};
#endif
}

std::string Environment::expandEnvByRegexp(const std::string& path, const std::regex& regex)
{
std::smatch matcher;
std::string result;
auto text = path;
while (std::regex_search(text, matcher, regex)) {
result += matcher.prefix().str();
auto env_value = getOSVariable(matcher[1].str().c_str());
if (env_value) {
// add expanded value
result += UStr::to_stdstr(env_value);
}
else {
// add variable name
result += matcher[0].str();
}
text = matcher.suffix().str();
}
result += text;

return result;
}

} // namespace colorer
11 changes: 9 additions & 2 deletions src/colorer/utils/Environment.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
#ifndef COLORER_ENVIRONMENT_H
#define COLORER_ENVIRONMENT_H

#include <regex>
#include <vector>
#include "colorer/Common.h"

#ifdef COLORER_FEATURE_OLD_COMPILERS
#include "colorer/platform/filesystem.hpp"
namespace fs = ghc::filesystem;
#else
#include <filesystem>
namespace fs = std::filesystem;
#endif
#include <vector>


namespace colorer {

class Environment
{
public:
static uUnicodeString getOSVariable(const UnicodeString& name);
static uUnicodeString expandEnvironment(const UnicodeString* path);
static uUnicodeString normalizePath(const UnicodeString* path);
static fs::path normalizeFsPath(const UnicodeString* path);
static fs::path getClearFilePath(const UnicodeString* basePath, const UnicodeString* relPath);
Expand All @@ -28,6 +31,10 @@ class Environment
static UnicodeString getAbsolutePath(const UnicodeString& basePath, const UnicodeString& relPath);

static UnicodeString expandSpecialEnvironment(const UnicodeString& path);
static UnicodeString expandEnvironment(const UnicodeString& path);

private:
static std::string expandEnvByRegexp(const std::string& path, const std::regex& regex);
};

} // namespace colorer
Expand Down
2 changes: 1 addition & 1 deletion src/colorer/xml/XmlInputSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ UnicodeString& XmlInputSource::getPath() const
return xml_input_source->getPath();
}

bool XmlInputSource::isFileURI(const UnicodeString& path, const UnicodeString* base)
bool XmlInputSource::isFsURI(const UnicodeString& path, const UnicodeString* base)
{
const UnicodeString jar(u"jar:");
if (path.startsWith(jar) || (base && base->startsWith(jar))) {
Expand Down
2 changes: 1 addition & 1 deletion src/colorer/xml/XmlInputSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class XmlInputSource
[[nodiscard]]
UnicodeString& getPath() const;

static bool isFileURI(const UnicodeString& path, const UnicodeString* base);
static bool isFsURI(const UnicodeString& path, const UnicodeString* base);

private:
std::unique_ptr<LibXmlInputSource> xml_input_source;
Expand Down
11 changes: 7 additions & 4 deletions src/colorer/xml/libxml2/LibXmlInputSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
LibXmlInputSource::LibXmlInputSource(const UnicodeString& path, const UnicodeString* base)
{
if (path.isEmpty()) {
throw InputSourceException("XmlInputSource::newInstance: path is empty");
throw InputSourceException("LibXmlInputSource: path is empty");
}
UnicodeString full_path;
if (path.startsWith(jar) || (base != nullptr && base->startsWith(jar))) {
Expand Down Expand Up @@ -43,15 +43,16 @@ UnicodeString& LibXmlInputSource::getPath()
}

#ifdef COLORER_FEATURE_ZIPINPUTSOURCE

void LibXmlInputSource::initZipSource(const UnicodeString& path, const UnicodeString* base)
{
auto paths = getFullPathFromPathJar(path, base);
const auto paths = getFullPathsToZip(path, base);

sourcePath = paths.full_path;
zip_source = SharedXmlInputSource::getSharedInputSource(paths.path_to_jar);
}

PathInJar LibXmlInputSource::getFullPathFromPathJar(const UnicodeString& path, const UnicodeString* base)
PathInJar LibXmlInputSource::getFullPathsToZip(const UnicodeString& path, const UnicodeString* base)
{
if (path.startsWith(jar)) {
const auto path_idx = path.lastIndexOf('!');
Expand All @@ -66,7 +67,7 @@ PathInJar LibXmlInputSource::getFullPathFromPathJar(const UnicodeString& path, c
const UnicodeString full_path = jar + path_to_jar + u"!" + path_in_jar;
return {full_path, path_to_jar, path_in_jar};
}
else {
if (base != nullptr && base->startsWith(jar)) {
const auto base_idx = base->lastIndexOf('!');
if (base_idx == -1) {
throw InputSourceException("Bad jar uri format: " + path);
Expand All @@ -77,5 +78,7 @@ PathInJar LibXmlInputSource::getFullPathFromPathJar(const UnicodeString& path, c
const UnicodeString full_path = jar + path_to_jar + u"!" + path_in_jar;
return {full_path, path_to_jar, path_in_jar};
}
throw InputSourceException("The path to the jar was not found");
}

#endif
6 changes: 3 additions & 3 deletions src/colorer/xml/libxml2/LibXmlInputSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class LibXmlInputSource
explicit LibXmlInputSource(const UnicodeString& path, const UnicodeString* base = nullptr);
~LibXmlInputSource();

[[nodiscard]]
LibXmlInputSource createRelative(const UnicodeString& relPath) const;

[[nodiscard]]
Expand All @@ -31,12 +32,11 @@ class LibXmlInputSource

#ifdef COLORER_FEATURE_ZIPINPUTSOURCE
public:
void initZipSource(const UnicodeString& path, const UnicodeString* base = nullptr);

static PathInJar getFullPathFromPathJar(const UnicodeString& path, const UnicodeString* base);
static PathInJar getFullPathsToZip(const UnicodeString& path, const UnicodeString* base = nullptr);

private:
SharedXmlInputSource* zip_source {nullptr};
void initZipSource(const UnicodeString& path, const UnicodeString* base = nullptr);
#endif
};

Expand Down
2 changes: 1 addition & 1 deletion src/colorer/xml/libxml2/LibXmlReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ xmlParserInputPtr LibXmlReader::xmlMyExternalEntityLoader(const char* URL, const
if (!is_full_path) {
string_url = colorer::Environment::expandSpecialEnvironment(string_url);
}
auto paths = LibXmlInputSource::getFullPathFromPathJar(string_url, is_full_path ? nullptr : current_file.get());
auto paths = LibXmlInputSource::getFullPathsToZip(string_url, is_full_path ? nullptr : current_file.get());
is_full_path = false;
xmlParserInputPtr ret = nullptr;
try {
Expand Down
2 changes: 1 addition & 1 deletion src/colorer/xml/libxml2/SharedXmlInputSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ SharedXmlInputSource::SharedXmlInputSource(const UnicodeString& path)

SharedXmlInputSource::~SharedXmlInputSource()
{
// не нужно удалять объект, удаляемый из массива. мы и так уже в деструкторе
// You don't need to delete an object that has been deleted from the array. We are already in the destructor.
isHash->erase(source_path);
if (isHash->empty()) {
delete isHash;
Expand Down
4 changes: 3 additions & 1 deletion tests/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ set(unit_tests_SRC
test_exception.cpp
test_filetype.cpp
test_environment.cpp
test_hrcparsing.cpp)
test_hrcparsing.cpp
test_xmlinputsource.cpp
)

add_executable(unit_tests ${unit_tests_SRC})

Expand Down
Loading

0 comments on commit a648b9d

Please sign in to comment.