aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-01-26 02:42:17 +0800
committerchriseth <c@ethdev.com>2016-01-26 04:01:55 +0800
commitdb2f3c57147c21da8a549a6052256540d3c41e3e (patch)
treeb8af9542c7aea99767b1c0bafd780803a56e7395
parent194679f77ada30b04f483e96197e890e41a0c22c (diff)
downloaddexon-solidity-db2f3c57147c21da8a549a6052256540d3c41e3e.tar
dexon-solidity-db2f3c57147c21da8a549a6052256540d3c41e3e.tar.gz
dexon-solidity-db2f3c57147c21da8a549a6052256540d3c41e3e.tar.bz2
dexon-solidity-db2f3c57147c21da8a549a6052256540d3c41e3e.tar.lz
dexon-solidity-db2f3c57147c21da8a549a6052256540d3c41e3e.tar.xz
dexon-solidity-db2f3c57147c21da8a549a6052256540d3c41e3e.tar.zst
dexon-solidity-db2f3c57147c21da8a549a6052256540d3c41e3e.zip
Provide remappings for solc.
-rw-r--r--solc/CommandLineInterface.cpp105
-rw-r--r--solc/CommandLineInterface.h4
2 files changed, 77 insertions, 32 deletions
diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp
index 4c9de3c8..7c842c83 100644
--- a/solc/CommandLineInterface.cpp
+++ b/solc/CommandLineInterface.cpp
@@ -297,6 +297,48 @@ void CommandLineInterface::handleFormal()
cout << "Formal version:" << endl << m_compiler->formalTranslation() << endl;
}
+void CommandLineInterface::readInputFilesAndConfigureRemappings()
+{
+ if (!m_args.count("input-file"))
+ {
+ string s;
+ while (!cin.eof())
+ {
+ getline(cin, s);
+ m_sourceCodes[g_stdinFileName].append(s + '\n');
+ }
+ }
+ else
+ for (string const& infile: m_args["input-file"].as<vector<string>>())
+ {
+ auto eq = find(infile.begin(), infile.end(), '=');
+ if (eq != infile.end())
+ m_remappings.push_back(make_pair(
+ string(infile.begin(), eq),
+ string(eq + 1, infile.end())
+ ));
+ else
+ {
+ auto path = boost::filesystem::path(infile);
+ if (!boost::filesystem::exists(path))
+ {
+ cerr << "Skipping non existant input file \"" << infile << "\"" << endl;
+ continue;
+ }
+
+ if (!boost::filesystem::is_regular_file(path))
+ {
+ cerr << "\"" << infile << "\" is not a valid file. Skipping" << endl;
+ continue;
+ }
+
+ m_sourceCodes[infile] = dev::contentsString(infile);
+ }
+ }
+ // Add empty remapping to try the path itself.
+ m_remappings.push_back(make_pair(string(), string()));
+}
+
bool CommandLineInterface::parseLibraryOption(string const& _input)
{
namespace fs = boost::filesystem;
@@ -457,33 +499,7 @@ Allowed options)",
bool CommandLineInterface::processInput()
{
- if (!m_args.count("input-file"))
- {
- string s;
- while (!cin.eof())
- {
- getline(cin, s);
- m_sourceCodes[g_stdinFileName].append(s + '\n');
- }
- }
- else
- for (string const& infile: m_args["input-file"].as<vector<string>>())
- {
- auto path = boost::filesystem::path(infile);
- if (!boost::filesystem::exists(path))
- {
- cerr << "Skipping non existant input file \"" << infile << "\"" << endl;
- continue;
- }
-
- if (!boost::filesystem::is_regular_file(path))
- {
- cerr << "\"" << infile << "\" is not a valid file. Skipping" << endl;
- continue;
- }
-
- m_sourceCodes[infile] = dev::contentsString(infile);
- }
+ readInputFilesAndConfigureRemappings();
if (m_args.count("libraries"))
for (string const& library: m_args["libraries"].as<vector<string>>())
@@ -499,13 +515,38 @@ bool CommandLineInterface::processInput()
function<pair<string,string>(string const&)> fileReader = [this](string const& _path)
{
- auto path = boost::filesystem::path(_path);
- if (!boost::filesystem::exists(path))
+ // Try to find the longest prefix match in all remappings. At the end, there will be an
+ // empty remapping so that we also try the path itself.
+ int errorLevel = 0;
+ size_t longestPrefix = 0;
+ string bestMatchPath;
+ for (auto const& redir: m_remappings)
+ {
+ auto const& virt = redir.first;
+ if (longestPrefix > 0 && virt.length() <= longestPrefix)
+ continue;
+ if (virt.length() > _path.length() || !std::equal(virt.begin(), virt.end(), _path.begin()))
+ continue;
+ string path = redir.second;
+ path.append(_path.begin() + virt.length(), _path.end());
+ auto boostPath = boost::filesystem::path(path);
+ if (!boost::filesystem::exists(boostPath))
+ errorLevel = max(errorLevel, 0);
+ else if (!boost::filesystem::is_regular_file(boostPath))
+ errorLevel = max(errorLevel, 1);
+ else
+ {
+ longestPrefix = virt.length();
+ bestMatchPath = path;
+ }
+ }
+ if (!bestMatchPath.empty())
+ return make_pair(m_sourceCodes[bestMatchPath] = dev::contentsString(bestMatchPath), string());
+ if (errorLevel == 0)
return make_pair(string(), string("File not found."));
- else if (!boost::filesystem::is_regular_file(path))
- return make_pair(string(), string("Not a valid file."));
else
- return make_pair(m_sourceCodes[_path] = dev::contentsString(_path), string());
+ return make_pair(string(), string("Not a valid file."));
+
};
m_compiler.reset(new CompilerStack(m_args.count(g_argAddStandard) > 0, fileReader));
diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h
index 7c7aa4b4..7fdc9c0d 100644
--- a/solc/CommandLineInterface.h
+++ b/solc/CommandLineInterface.h
@@ -61,6 +61,8 @@ private:
void handleGasEstimation(std::string const& _contract);
void handleFormal();
+ /// Fills @a m_sourceCodes initially and @a m_redirects.
+ void readInputFilesAndConfigureRemappings();
/// Tries to read from the file @a _input or interprets _input literally if that fails.
/// It then tries to parse the contents and appends to m_libraries.
bool parseLibraryOption(std::string const& _input);
@@ -76,6 +78,8 @@ private:
boost::program_options::variables_map m_args;
/// map of input files to source code strings
std::map<std::string, std::string> m_sourceCodes;
+ /// list of path prefix remappings, e.g. github.com/ethereum -> /usr/local/ethereum
+ std::vector<std::pair<std::string, std::string>> m_remappings;
/// map of library names to addresses
std::map<std::string, h160> m_libraries;
/// Solidity compiler stack