LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
path_resolver.cpp
Go to the documentation of this file.
1// Copyright 2021 CEA LIST
2// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3//
4// SPDX-License-Identifier: MIT
5
6#include <cstdlib>
7#include <iostream>
8#include <sstream>
9#include <vector>
10
11#include <boost/filesystem.hpp>
12
13#include "path_resolver.h"
14
15using namespace std;
16namespace fs = boost::filesystem;
17
18namespace deeplima
19{
20
21PathResolver::PathResolver(const std::string& paths)
22{
23 init(paths);
24}
25
26string PathResolver::resolve(const string& prefix, const string& path, const vector<string>& accepted_ext) const
27{
28 fs::path p;
29 if (prefix.empty())
30 {
31 p = path;
32 }
33 else
34 {
35 p = fs::path(prefix) / path;
36 }
37
38 if (p.is_absolute())
39 {
40 return p.string();
41 }
42
43 vector<string> candidates = { p.string() };
44 if (!p.extension().empty())
45 {
46 candidates.push_back(p.stem().string());
47 }
48
49 for (const string& resources_path : m_resources_paths)
50 {
51 for (const string& fn : candidates)
52 {
53 if (fn.empty())
54 {
55 continue;
56 }
57
58 fs::path full_path = fs::path(resources_path) / fn;
59 if (fs::is_regular_file(full_path) || fs::is_symlink(full_path))
60 {
61 return full_path.string();
62 }
63
64 for (const string& ext : accepted_ext)
65 {
66 if (ext.empty())
67 {
68 continue;
69 }
70
71 full_path = fs::path(resources_path) / fn;
72 if (ext.substr(0, 1) != ".")
73 {
74 full_path += ".";
75 }
76 full_path += ext;
77
78 if (fs::is_regular_file(full_path) || fs::is_symlink(full_path))
79 {
80 return full_path.string();
81 }
82 }
83 }
84 }
85
86 return "";
87}
88
90{
91 fs::path user_data_home;
92 const char* p_xdg_data_home = getenv("XDG_DATA_HOME");
93
94 if (nullptr != p_xdg_data_home)
95 {
96 user_data_home = p_xdg_data_home;
97 }
98
99 if (user_data_home.empty())
100 {
101 user_data_home = getenv("HOME");
102 if (!user_data_home.empty())
103 {
104 user_data_home = user_data_home / ".local" / "share";
105 }
106 }
107
108 return user_data_home.string();
109}
110
111std::vector<std::string> split (const std::string &s, char delim) {
112 std::vector<std::string> result;
113 std::stringstream ss (s);
114 std::string item;
115
116 while (getline (ss, item, delim)) {
117 result.push_back (item);
118 }
119
120 return result;
121}
122
123void PathResolver::init(const std::string& paths)
124{
125 auto var = std::getenv("LIMA_RESOURCES");
126 auto dirs = split(paths, ':');
127 if (var)
128 {
129 dirs = split(var, ':');
130 }
131 m_resources_paths.insert(std::end(m_resources_paths), std::begin(dirs), std::end(dirs));
132 fs::path user_data_home = find_user_data_home();
133 if (!user_data_home.empty())
134 {
135 m_resources_paths.emplace_back((user_data_home / "lima" / "resources").string());
136 }
137}
138
139}
140
void init(const std::string &paths="")
PathResolver(const std::string &paths="")
std::string resolve(const std::string &prefix, const std::string &path, const std::vector< std::string > &accepted_ext={}) const
std::vector< std::string > m_resources_paths
std::string find_user_data_home()
std::vector< std::string > split(const std::string &s, char delim)
STL namespace.