Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit db2f3c5

Browse files
committed
Provide remappings for solc.
1 parent 194679f commit db2f3c5

File tree

2 files changed

+77
-32
lines changed

2 files changed

+77
-32
lines changed

solc/CommandLineInterface.cpp

Lines changed: 73 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,48 @@ void CommandLineInterface::handleFormal()
297297
cout << "Formal version:" << endl << m_compiler->formalTranslation() << endl;
298298
}
299299

300+
void CommandLineInterface::readInputFilesAndConfigureRemappings()
301+
{
302+
if (!m_args.count("input-file"))
303+
{
304+
string s;
305+
while (!cin.eof())
306+
{
307+
getline(cin, s);
308+
m_sourceCodes[g_stdinFileName].append(s + '\n');
309+
}
310+
}
311+
else
312+
for (string const& infile: m_args["input-file"].as<vector<string>>())
313+
{
314+
auto eq = find(infile.begin(), infile.end(), '=');
315+
if (eq != infile.end())
316+
m_remappings.push_back(make_pair(
317+
string(infile.begin(), eq),
318+
string(eq + 1, infile.end())
319+
));
320+
else
321+
{
322+
auto path = boost::filesystem::path(infile);
323+
if (!boost::filesystem::exists(path))
324+
{
325+
cerr << "Skipping non existant input file \"" << infile << "\"" << endl;
326+
continue;
327+
}
328+
329+
if (!boost::filesystem::is_regular_file(path))
330+
{
331+
cerr << "\"" << infile << "\" is not a valid file. Skipping" << endl;
332+
continue;
333+
}
334+
335+
m_sourceCodes[infile] = dev::contentsString(infile);
336+
}
337+
}
338+
// Add empty remapping to try the path itself.
339+
m_remappings.push_back(make_pair(string(), string()));
340+
}
341+
300342
bool CommandLineInterface::parseLibraryOption(string const& _input)
301343
{
302344
namespace fs = boost::filesystem;
@@ -457,33 +499,7 @@ Allowed options)",
457499

458500
bool CommandLineInterface::processInput()
459501
{
460-
if (!m_args.count("input-file"))
461-
{
462-
string s;
463-
while (!cin.eof())
464-
{
465-
getline(cin, s);
466-
m_sourceCodes[g_stdinFileName].append(s + '\n');
467-
}
468-
}
469-
else
470-
for (string const& infile: m_args["input-file"].as<vector<string>>())
471-
{
472-
auto path = boost::filesystem::path(infile);
473-
if (!boost::filesystem::exists(path))
474-
{
475-
cerr << "Skipping non existant input file \"" << infile << "\"" << endl;
476-
continue;
477-
}
478-
479-
if (!boost::filesystem::is_regular_file(path))
480-
{
481-
cerr << "\"" << infile << "\" is not a valid file. Skipping" << endl;
482-
continue;
483-
}
484-
485-
m_sourceCodes[infile] = dev::contentsString(infile);
486-
}
502+
readInputFilesAndConfigureRemappings();
487503

488504
if (m_args.count("libraries"))
489505
for (string const& library: m_args["libraries"].as<vector<string>>())
@@ -499,13 +515,38 @@ bool CommandLineInterface::processInput()
499515

500516
function<pair<string,string>(string const&)> fileReader = [this](string const& _path)
501517
{
502-
auto path = boost::filesystem::path(_path);
503-
if (!boost::filesystem::exists(path))
518+
// Try to find the longest prefix match in all remappings. At the end, there will be an
519+
// empty remapping so that we also try the path itself.
520+
int errorLevel = 0;
521+
size_t longestPrefix = 0;
522+
string bestMatchPath;
523+
for (auto const& redir: m_remappings)
524+
{
525+
auto const& virt = redir.first;
526+
if (longestPrefix > 0 && virt.length() <= longestPrefix)
527+
continue;
528+
if (virt.length() > _path.length() || !std::equal(virt.begin(), virt.end(), _path.begin()))
529+
continue;
530+
string path = redir.second;
531+
path.append(_path.begin() + virt.length(), _path.end());
532+
auto boostPath = boost::filesystem::path(path);
533+
if (!boost::filesystem::exists(boostPath))
534+
errorLevel = max(errorLevel, 0);
535+
else if (!boost::filesystem::is_regular_file(boostPath))
536+
errorLevel = max(errorLevel, 1);
537+
else
538+
{
539+
longestPrefix = virt.length();
540+
bestMatchPath = path;
541+
}
542+
}
543+
if (!bestMatchPath.empty())
544+
return make_pair(m_sourceCodes[bestMatchPath] = dev::contentsString(bestMatchPath), string());
545+
if (errorLevel == 0)
504546
return make_pair(string(), string("File not found."));
505-
else if (!boost::filesystem::is_regular_file(path))
506-
return make_pair(string(), string("Not a valid file."));
507547
else
508-
return make_pair(m_sourceCodes[_path] = dev::contentsString(_path), string());
548+
return make_pair(string(), string("Not a valid file."));
549+
509550
};
510551

511552
m_compiler.reset(new CompilerStack(m_args.count(g_argAddStandard) > 0, fileReader));

solc/CommandLineInterface.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class CommandLineInterface
6161
void handleGasEstimation(std::string const& _contract);
6262
void handleFormal();
6363

64+
/// Fills @a m_sourceCodes initially and @a m_redirects.
65+
void readInputFilesAndConfigureRemappings();
6466
/// Tries to read from the file @a _input or interprets _input literally if that fails.
6567
/// It then tries to parse the contents and appends to m_libraries.
6668
bool parseLibraryOption(std::string const& _input);
@@ -76,6 +78,8 @@ class CommandLineInterface
7678
boost::program_options::variables_map m_args;
7779
/// map of input files to source code strings
7880
std::map<std::string, std::string> m_sourceCodes;
81+
/// list of path prefix remappings, e.g. github.com/ethereum -> /usr/local/ethereum
82+
std::vector<std::pair<std::string, std::string>> m_remappings;
7983
/// map of library names to addresses
8084
std::map<std::string, h160> m_libraries;
8185
/// Solidity compiler stack

0 commit comments

Comments
 (0)