Skip to content

Commit

Permalink
Introduce 'argv0' parameter to SimpleConverter, and fix Bazel bundled…
Browse files Browse the repository at this point in the history
… paths of runfiles.
  • Loading branch information
BYVoid committed Jul 28, 2024
1 parent 452617f commit 562ff89
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 27 deletions.
46 changes: 32 additions & 14 deletions src/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,7 @@ class ConfigInternal {
return chain;
}

std::string FindConfigFile(std::string fileName,
const std::vector<std::string>& configPaths) {
std::string FindConfigFile(std::string fileName) {
std::ifstream ifs;

// Working directory
Expand All @@ -194,7 +193,7 @@ class ConfigInternal {
}
}

for (const std::string& dirPath : configPaths) {
for (const std::string& dirPath : paths) {
std::string path = dirPath + '/' + fileName;
ifs.open(UTF8Util::GetPlatformString(path).c_str());
if (ifs.is_open()) {
Expand All @@ -205,16 +204,39 @@ class ConfigInternal {
throw FileNotFound(fileName);
}
};

std::string GetParentDirectory(const std::string& path) {
size_t pos = path.rfind('/', path.length() - 1);
if (pos == std::string::npos) {
pos = path.rfind('\\', path.length() - 1);
}
if (pos == std::string::npos) {
return "";
}
return path.substr(0, pos + 1);
}

} // namespace

Config::Config() : internal(new ConfigInternal()) {}

Config::~Config() { delete (ConfigInternal*)internal; }
Config::~Config() { delete reinterpret_cast<ConfigInternal*>(internal); }

ConverterPtr Config::NewFromFile(const std::string& fileName,
const std::vector<std::string>& paths) {
ConfigInternal* impl = (ConfigInternal*)internal;
std::string prefixedFileName = impl->FindConfigFile(fileName, paths);
const std::vector<std::string>& paths,
const char* argv0) {
ConfigInternal* impl = reinterpret_cast<ConfigInternal*>(internal);
impl->paths = paths;
if (argv0 != nullptr) {
std::string parent = GetParentDirectory(argv0);
if (!parent.empty()) {
impl->paths.push_back(parent);
}
}
if (PACKAGE_DATA_DIRECTORY != "") {
impl->paths.push_back(PACKAGE_DATA_DIRECTORY);
}
std::string prefixedFileName = impl->FindConfigFile(fileName);
std::ifstream ifs(UTF8Util::GetPlatformString(prefixedFileName));
std::string content(std::istreambuf_iterator<char>(ifs),
(std::istreambuf_iterator<char>()));
Expand All @@ -227,11 +249,10 @@ ConverterPtr Config::NewFromFile(const std::string& fileName,
if (slashPos != std::string::npos) {
configDirectory = prefixedFileName.substr(0, slashPos) + "/";
}
std::vector<std::string> dictPaths = paths;
if (!configDirectory.empty()) {
dictPaths.push_back(configDirectory);
impl->paths.push_back(configDirectory);
}
return NewFromString(content, dictPaths);
return NewFromString(content, impl->paths);
}

ConverterPtr Config::NewFromString(const std::string& json,
Expand Down Expand Up @@ -265,11 +286,8 @@ ConverterPtr Config::NewFromString(const std::string& json,
name = doc["name"].GetString();
}

ConfigInternal* impl = (ConfigInternal*)internal;
ConfigInternal* impl = reinterpret_cast<ConfigInternal*>(internal);
impl->paths = paths;
if (PACKAGE_DATA_DIRECTORY != "") {
impl->paths.push_back(PACKAGE_DATA_DIRECTORY);
}

// Required: segmentation
SegmentationPtr segmentation =
Expand Down
3 changes: 2 additions & 1 deletion src/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class OPENCC_EXPORT Config {
const std::vector<std::string>& paths);

ConverterPtr NewFromFile(const std::string& fileName,
const std::vector<std::string>& paths = {});
const std::vector<std::string>& paths = {},
const char* argv0 = nullptr);

private:
void* internal;
Expand Down
38 changes: 26 additions & 12 deletions src/SimpleConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,29 @@ struct InternalData {
InternalData(const ConverterPtr& _converter) : converter(_converter) {}

static InternalData* NewInternalData(const std::string& configFileName,
const std::vector<std::string>& paths) {
const std::vector<std::string>& paths,
const char* argv0) {
try {
Config config;
#ifdef BAZEL
std::unique_ptr<Runfiles> bazel_runfiles(Runfiles::Create(""));
std::vector<std::string> paths_with_runfiles = paths;
paths_with_runfiles.push_back(
bazel_runfiles->Rlocation("_main/data/config"));
paths_with_runfiles.push_back(
bazel_runfiles->Rlocation("_main/data/dictionary"));
return new InternalData(
config.NewFromFile(configFileName, paths_with_runfiles));
#else
return new InternalData(config.NewFromFile(configFileName, paths));
std::string err;
std::unique_ptr<Runfiles> bazel_runfiles(
Runfiles::Create(argv0 != nullptr ? argv0 : "", &err));
if (bazel_runfiles != nullptr) {
std::vector<std::string> paths_with_runfiles = paths;
paths_with_runfiles.push_back(
bazel_runfiles->Rlocation("opencc~/data/config"));
paths_with_runfiles.push_back(
bazel_runfiles->Rlocation("opencc~/data/dictionary"));
paths_with_runfiles.push_back(
bazel_runfiles->Rlocation("_main/data/config"));
paths_with_runfiles.push_back(
bazel_runfiles->Rlocation("_main/data/dictionary"));
return new InternalData(
config.NewFromFile(configFileName, paths_with_runfiles));
}
#endif
return new InternalData(config.NewFromFile(configFileName, paths, argv0));
} catch (Exception& ex) {
throw std::runtime_error(ex.what());
}
Expand All @@ -64,7 +72,13 @@ SimpleConverter::SimpleConverter(const std::string& configFileName)

SimpleConverter::SimpleConverter(const std::string& configFileName,
const std::vector<std::string>& paths)
: internalData(InternalData::NewInternalData(configFileName, paths)) {}
: SimpleConverter(configFileName, paths, nullptr) {}

SimpleConverter::SimpleConverter(const std::string& configFileName,
const std::vector<std::string>& paths,
const char* argv0)
: internalData(
InternalData::NewInternalData(configFileName, paths, argv0)) {}

SimpleConverter::~SimpleConverter() { delete (InternalData*)internalData; }

Expand Down
10 changes: 10 additions & 0 deletions src/SimpleConverter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ class OPENCC_EXPORT SimpleConverter {
SimpleConverter(const std::string& configFileName,
const std::vector<std::string>& paths);

/**
* Constructor of SimpleConverter
* @param configFileName File name of configuration.
* @param paths Additional paths to locate configuration and dictionary files.
* @param argv0 Path of the executable (argv[0]), in addition to additional
* paths.
*/
SimpleConverter(const std::string& configFileName,
const std::vector<std::string>& paths, const char* argv0);

~SimpleConverter();

/**
Expand Down

0 comments on commit 562ff89

Please sign in to comment.