mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #4958 from liangdzou/issue_4494_error_out_when_no_output_required
Error out if no output artifacts are requested.
This commit is contained in:
commit
3e44115c69
@ -70,6 +70,24 @@ namespace dev
|
|||||||
namespace solidity
|
namespace solidity
|
||||||
{
|
{
|
||||||
|
|
||||||
|
bool g_hasOutput = false;
|
||||||
|
|
||||||
|
std::ostream& sout()
|
||||||
|
{
|
||||||
|
g_hasOutput = true;
|
||||||
|
return cout;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& serr(bool _used = true)
|
||||||
|
{
|
||||||
|
if (_used)
|
||||||
|
g_hasOutput = true;
|
||||||
|
return cerr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define cout
|
||||||
|
#define cerr
|
||||||
|
|
||||||
static string const g_stdinFileNameStr = "<stdin>";
|
static string const g_stdinFileNameStr = "<stdin>";
|
||||||
static string const g_strAbi = "abi";
|
static string const g_strAbi = "abi";
|
||||||
static string const g_strAllowPaths = "allow-paths";
|
static string const g_strAllowPaths = "allow-paths";
|
||||||
@ -181,7 +199,7 @@ static set<string> const g_machineArgs
|
|||||||
|
|
||||||
static void version()
|
static void version()
|
||||||
{
|
{
|
||||||
cout <<
|
sout() <<
|
||||||
"solc, the solidity compiler commandline interface" <<
|
"solc, the solidity compiler commandline interface" <<
|
||||||
endl <<
|
endl <<
|
||||||
"Version: " <<
|
"Version: " <<
|
||||||
@ -192,9 +210,9 @@ static void version()
|
|||||||
|
|
||||||
static void license()
|
static void license()
|
||||||
{
|
{
|
||||||
cout << otherLicenses << endl;
|
sout() << otherLicenses << endl;
|
||||||
// This is a static variable generated by cmake from LICENSE.txt
|
// This is a static variable generated by cmake from LICENSE.txt
|
||||||
cout << licenseText << endl;
|
sout() << licenseText << endl;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,8 +248,8 @@ void CommandLineInterface::handleBinary(string const& _contract)
|
|||||||
createFile(m_compiler->filesystemFriendlyName(_contract) + ".bin", objectWithLinkRefsHex(m_compiler->object(_contract)));
|
createFile(m_compiler->filesystemFriendlyName(_contract) + ".bin", objectWithLinkRefsHex(m_compiler->object(_contract)));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Binary: " << endl;
|
sout() << "Binary: " << endl;
|
||||||
cout << objectWithLinkRefsHex(m_compiler->object(_contract)) << endl;
|
sout() << objectWithLinkRefsHex(m_compiler->object(_contract)) << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_args.count(g_argBinaryRuntime))
|
if (m_args.count(g_argBinaryRuntime))
|
||||||
@ -240,8 +258,8 @@ void CommandLineInterface::handleBinary(string const& _contract)
|
|||||||
createFile(m_compiler->filesystemFriendlyName(_contract) + ".bin-runtime", objectWithLinkRefsHex(m_compiler->runtimeObject(_contract)));
|
createFile(m_compiler->filesystemFriendlyName(_contract) + ".bin-runtime", objectWithLinkRefsHex(m_compiler->runtimeObject(_contract)));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Binary of the runtime part: " << endl;
|
sout() << "Binary of the runtime part: " << endl;
|
||||||
cout << objectWithLinkRefsHex(m_compiler->runtimeObject(_contract)) << endl;
|
sout() << objectWithLinkRefsHex(m_compiler->runtimeObject(_contract)) << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,9 +270,9 @@ void CommandLineInterface::handleOpcode(string const& _contract)
|
|||||||
createFile(m_compiler->filesystemFriendlyName(_contract) + ".opcode", solidity::disassemble(m_compiler->object(_contract).bytecode));
|
createFile(m_compiler->filesystemFriendlyName(_contract) + ".opcode", solidity::disassemble(m_compiler->object(_contract).bytecode));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Opcodes: " << endl;
|
sout() << "Opcodes: " << endl;
|
||||||
cout << solidity::disassemble(m_compiler->object(_contract).bytecode);
|
sout() << solidity::disassemble(m_compiler->object(_contract).bytecode);
|
||||||
cout << endl;
|
sout() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +297,7 @@ void CommandLineInterface::handleSignatureHashes(string const& _contract)
|
|||||||
if (m_args.count(g_argOutputDir))
|
if (m_args.count(g_argOutputDir))
|
||||||
createFile(m_compiler->filesystemFriendlyName(_contract) + ".signatures", out);
|
createFile(m_compiler->filesystemFriendlyName(_contract) + ".signatures", out);
|
||||||
else
|
else
|
||||||
cout << "Function signatures: " << endl << out;
|
sout() << "Function signatures: " << endl << out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandLineInterface::handleMetadata(string const& _contract)
|
void CommandLineInterface::handleMetadata(string const& _contract)
|
||||||
@ -291,7 +309,7 @@ void CommandLineInterface::handleMetadata(string const& _contract)
|
|||||||
if (m_args.count(g_argOutputDir))
|
if (m_args.count(g_argOutputDir))
|
||||||
createFile(m_compiler->filesystemFriendlyName(_contract) + "_meta.json", data);
|
createFile(m_compiler->filesystemFriendlyName(_contract) + "_meta.json", data);
|
||||||
else
|
else
|
||||||
cout << "Metadata: " << endl << data << endl;
|
sout() << "Metadata: " << endl << data << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandLineInterface::handleABI(string const& _contract)
|
void CommandLineInterface::handleABI(string const& _contract)
|
||||||
@ -303,7 +321,7 @@ void CommandLineInterface::handleABI(string const& _contract)
|
|||||||
if (m_args.count(g_argOutputDir))
|
if (m_args.count(g_argOutputDir))
|
||||||
createFile(m_compiler->filesystemFriendlyName(_contract) + ".abi", data);
|
createFile(m_compiler->filesystemFriendlyName(_contract) + ".abi", data);
|
||||||
else
|
else
|
||||||
cout << "Contract JSON ABI " << endl << data << endl;
|
sout() << "Contract JSON ABI " << endl << data << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandLineInterface::handleNatspec(bool _natspecDev, string const& _contract)
|
void CommandLineInterface::handleNatspec(bool _natspecDev, string const& _contract)
|
||||||
@ -337,8 +355,8 @@ void CommandLineInterface::handleNatspec(bool _natspecDev, string const& _contra
|
|||||||
createFile(m_compiler->filesystemFriendlyName(_contract) + suffix, output);
|
createFile(m_compiler->filesystemFriendlyName(_contract) + suffix, output);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << title << endl;
|
sout() << title << endl;
|
||||||
cout << output << endl;
|
sout() << output << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -347,39 +365,39 @@ void CommandLineInterface::handleNatspec(bool _natspecDev, string const& _contra
|
|||||||
void CommandLineInterface::handleGasEstimation(string const& _contract)
|
void CommandLineInterface::handleGasEstimation(string const& _contract)
|
||||||
{
|
{
|
||||||
Json::Value estimates = m_compiler->gasEstimates(_contract);
|
Json::Value estimates = m_compiler->gasEstimates(_contract);
|
||||||
cout << "Gas estimation:" << endl;
|
sout() << "Gas estimation:" << endl;
|
||||||
|
|
||||||
if (estimates["creation"].isObject())
|
if (estimates["creation"].isObject())
|
||||||
{
|
{
|
||||||
Json::Value creation = estimates["creation"];
|
Json::Value creation = estimates["creation"];
|
||||||
cout << "construction:" << endl;
|
sout() << "construction:" << endl;
|
||||||
cout << " " << creation["executionCost"].asString();
|
sout() << " " << creation["executionCost"].asString();
|
||||||
cout << " + " << creation["codeDepositCost"].asString();
|
sout() << " + " << creation["codeDepositCost"].asString();
|
||||||
cout << " = " << creation["totalCost"].asString() << endl;
|
sout() << " = " << creation["totalCost"].asString() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (estimates["external"].isObject())
|
if (estimates["external"].isObject())
|
||||||
{
|
{
|
||||||
Json::Value externalFunctions = estimates["external"];
|
Json::Value externalFunctions = estimates["external"];
|
||||||
cout << "external:" << endl;
|
sout() << "external:" << endl;
|
||||||
for (auto const& name: externalFunctions.getMemberNames())
|
for (auto const& name: externalFunctions.getMemberNames())
|
||||||
{
|
{
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
cout << " fallback:\t";
|
sout() << " fallback:\t";
|
||||||
else
|
else
|
||||||
cout << " " << name << ":\t";
|
sout() << " " << name << ":\t";
|
||||||
cout << externalFunctions[name].asString() << endl;
|
sout() << externalFunctions[name].asString() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (estimates["internal"].isObject())
|
if (estimates["internal"].isObject())
|
||||||
{
|
{
|
||||||
Json::Value internalFunctions = estimates["internal"];
|
Json::Value internalFunctions = estimates["internal"];
|
||||||
cout << "internal:" << endl;
|
sout() << "internal:" << endl;
|
||||||
for (auto const& name: internalFunctions.getMemberNames())
|
for (auto const& name: internalFunctions.getMemberNames())
|
||||||
{
|
{
|
||||||
cout << " " << name << ":\t";
|
sout() << " " << name << ":\t";
|
||||||
cout << internalFunctions[name].asString() << endl;
|
sout() << internalFunctions[name].asString() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -401,7 +419,7 @@ bool CommandLineInterface::readInputFilesAndConfigureRemappings()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "Invalid remapping: \"" << path << "\"." << endl;
|
serr() << "Invalid remapping: \"" << path << "\"." << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -414,11 +432,11 @@ bool CommandLineInterface::readInputFilesAndConfigureRemappings()
|
|||||||
{
|
{
|
||||||
if (!ignoreMissing)
|
if (!ignoreMissing)
|
||||||
{
|
{
|
||||||
cerr << infile << " is not found." << endl;
|
serr() << infile << " is not found." << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cerr << infile << " is not found. Skipping." << endl;
|
serr() << infile << " is not found. Skipping." << endl;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -427,11 +445,11 @@ bool CommandLineInterface::readInputFilesAndConfigureRemappings()
|
|||||||
{
|
{
|
||||||
if (!ignoreMissing)
|
if (!ignoreMissing)
|
||||||
{
|
{
|
||||||
cerr << infile << " is not a valid file." << endl;
|
serr() << infile << " is not a valid file." << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cerr << infile << " is not a valid file. Skipping." << endl;
|
serr() << infile << " is not a valid file. Skipping." << endl;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -445,7 +463,7 @@ bool CommandLineInterface::readInputFilesAndConfigureRemappings()
|
|||||||
m_sourceCodes[g_stdinFileName] = dev::readStandardInput();
|
m_sourceCodes[g_stdinFileName] = dev::readStandardInput();
|
||||||
if (m_sourceCodes.size() == 0)
|
if (m_sourceCodes.size() == 0)
|
||||||
{
|
{
|
||||||
cerr << "No input files given. If you wish to use the standard input please specify \"-\" explicitly." << endl;
|
serr() << "No input files given. If you wish to use the standard input please specify \"-\" explicitly." << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +494,7 @@ bool CommandLineInterface::parseLibraryOption(string const& _input)
|
|||||||
auto colon = lib.rfind(':');
|
auto colon = lib.rfind(':');
|
||||||
if (colon == string::npos)
|
if (colon == string::npos)
|
||||||
{
|
{
|
||||||
cerr << "Colon separator missing in library address specifier \"" << lib << "\"" << endl;
|
serr() << "Colon separator missing in library address specifier \"" << lib << "\"" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
string libName(lib.begin(), lib.begin() + colon);
|
string libName(lib.begin(), lib.begin() + colon);
|
||||||
@ -487,26 +505,26 @@ bool CommandLineInterface::parseLibraryOption(string const& _input)
|
|||||||
addrString = addrString.substr(2);
|
addrString = addrString.substr(2);
|
||||||
if (addrString.empty())
|
if (addrString.empty())
|
||||||
{
|
{
|
||||||
cerr << "Empty address provided for library \"" << libName << "\": " << endl;
|
serr() << "Empty address provided for library \"" << libName << "\": " << endl;
|
||||||
cerr << "Note that there should not be any whitespace after the colon." << endl;
|
serr() << "Note that there should not be any whitespace after the colon." << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (addrString.length() != 40)
|
else if (addrString.length() != 40)
|
||||||
{
|
{
|
||||||
cerr << "Invalid length for address for library \"" << libName << "\": " << addrString.length() << " instead of 40 characters." << endl;
|
serr() << "Invalid length for address for library \"" << libName << "\": " << addrString.length() << " instead of 40 characters." << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!passesAddressChecksum(addrString, false))
|
if (!passesAddressChecksum(addrString, false))
|
||||||
{
|
{
|
||||||
cerr << "Invalid checksum on address for library \"" << libName << "\": " << addrString << endl;
|
serr() << "Invalid checksum on address for library \"" << libName << "\": " << addrString << endl;
|
||||||
cerr << "The correct checksum is " << dev::getChecksummedAddress(addrString) << endl;
|
serr() << "The correct checksum is " << dev::getChecksummedAddress(addrString) << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bytes binAddr = fromHex(addrString);
|
bytes binAddr = fromHex(addrString);
|
||||||
h160 address(binAddr, h160::AlignRight);
|
h160 address(binAddr, h160::AlignRight);
|
||||||
if (binAddr.size() > 20 || address == h160())
|
if (binAddr.size() > 20 || address == h160())
|
||||||
{
|
{
|
||||||
cerr << "Invalid address for library \"" << libName << "\": " << addrString << endl;
|
serr() << "Invalid address for library \"" << libName << "\": " << addrString << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_libraries[libName] = address;
|
m_libraries[libName] = address;
|
||||||
@ -526,7 +544,7 @@ void CommandLineInterface::createFile(string const& _fileName, string const& _da
|
|||||||
string pathName = (p / _fileName).string();
|
string pathName = (p / _fileName).string();
|
||||||
if (fs::exists(pathName) && !m_args.count(g_strOverwrite))
|
if (fs::exists(pathName) && !m_args.count(g_strOverwrite))
|
||||||
{
|
{
|
||||||
cerr << "Refusing to overwrite existing file \"" << pathName << "\" (use --overwrite to force)." << endl;
|
serr() << "Refusing to overwrite existing file \"" << pathName << "\" (use --overwrite to force)." << endl;
|
||||||
m_error = true;
|
m_error = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -543,6 +561,8 @@ void CommandLineInterface::createJson(string const& _fileName, string const& _js
|
|||||||
|
|
||||||
bool CommandLineInterface::parseArguments(int _argc, char** _argv)
|
bool CommandLineInterface::parseArguments(int _argc, char** _argv)
|
||||||
{
|
{
|
||||||
|
g_hasOutput = false;
|
||||||
|
|
||||||
// Declare the supported options.
|
// Declare the supported options.
|
||||||
po::options_description desc(R"(solc, the Solidity commandline compiler.
|
po::options_description desc(R"(solc, the Solidity commandline compiler.
|
||||||
|
|
||||||
@ -667,13 +687,13 @@ Allowed options)",
|
|||||||
}
|
}
|
||||||
catch (po::error const& _exception)
|
catch (po::error const& _exception)
|
||||||
{
|
{
|
||||||
cerr << _exception.what() << endl;
|
serr() << _exception.what() << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_args.count(g_argHelp) || (isatty(fileno(stdin)) && _argc == 1))
|
if (m_args.count(g_argHelp) || (isatty(fileno(stdin)) && _argc == 1))
|
||||||
{
|
{
|
||||||
cout << desc;
|
sout() << desc;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -695,7 +715,7 @@ Allowed options)",
|
|||||||
for (string const& item: boost::split(requests, m_args[g_argCombinedJson].as<string>(), boost::is_any_of(",")))
|
for (string const& item: boost::split(requests, m_args[g_argCombinedJson].as<string>(), boost::is_any_of(",")))
|
||||||
if (!g_combinedJsonArgs.count(item))
|
if (!g_combinedJsonArgs.count(item))
|
||||||
{
|
{
|
||||||
cerr << "Invalid option to --combined-json: " << item << endl;
|
serr() << "Invalid option to --combined-json: " << item << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -759,9 +779,7 @@ bool CommandLineInterface::processInput()
|
|||||||
// path comparison in later parts of the code, so we need to strip
|
// path comparison in later parts of the code, so we need to strip
|
||||||
// it.
|
// it.
|
||||||
if (filesystem_path.filename() == ".")
|
if (filesystem_path.filename() == ".")
|
||||||
{
|
|
||||||
filesystem_path.remove_filename();
|
filesystem_path.remove_filename();
|
||||||
}
|
|
||||||
m_allowedDirectories.push_back(filesystem_path);
|
m_allowedDirectories.push_back(filesystem_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -770,7 +788,7 @@ bool CommandLineInterface::processInput()
|
|||||||
{
|
{
|
||||||
string input = dev::readStandardInput();
|
string input = dev::readStandardInput();
|
||||||
StandardCompiler compiler(fileReader);
|
StandardCompiler compiler(fileReader);
|
||||||
cout << compiler.compile(input) << endl;
|
sout() << compiler.compile(input) << endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -788,7 +806,7 @@ bool CommandLineInterface::processInput()
|
|||||||
boost::optional<EVMVersion> versionOption = EVMVersion::fromString(versionOptionStr);
|
boost::optional<EVMVersion> versionOption = EVMVersion::fromString(versionOptionStr);
|
||||||
if (!versionOption)
|
if (!versionOption)
|
||||||
{
|
{
|
||||||
cerr << "Invalid option for --evm-version: " << versionOptionStr << endl;
|
serr() << "Invalid option for --evm-version: " << versionOptionStr << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_evmVersion = *versionOption;
|
m_evmVersion = *versionOption;
|
||||||
@ -813,7 +831,7 @@ bool CommandLineInterface::processInput()
|
|||||||
targetMachine = Machine::eWasm;
|
targetMachine = Machine::eWasm;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "Invalid option for --machine: " << machine << endl;
|
serr() << "Invalid option for --machine: " << machine << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -829,7 +847,7 @@ bool CommandLineInterface::processInput()
|
|||||||
m_compiler.reset(new CompilerStack(fileReader));
|
m_compiler.reset(new CompilerStack(fileReader));
|
||||||
|
|
||||||
auto scannerFromSourceName = [&](string const& _sourceName) -> Scanner const& { return m_compiler->scanner(_sourceName); };
|
auto scannerFromSourceName = [&](string const& _sourceName) -> Scanner const& { return m_compiler->scanner(_sourceName); };
|
||||||
SourceReferenceFormatter formatter(cerr, scannerFromSourceName);
|
SourceReferenceFormatter formatter(serr(false), scannerFromSourceName);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -850,48 +868,55 @@ bool CommandLineInterface::processInput()
|
|||||||
bool successful = m_compiler->compile();
|
bool successful = m_compiler->compile();
|
||||||
|
|
||||||
for (auto const& error: m_compiler->errors())
|
for (auto const& error: m_compiler->errors())
|
||||||
|
{
|
||||||
|
g_hasOutput = true;
|
||||||
formatter.printExceptionInformation(
|
formatter.printExceptionInformation(
|
||||||
*error,
|
*error,
|
||||||
(error->type() == Error::Type::Warning) ? "Warning" : "Error"
|
(error->type() == Error::Type::Warning) ? "Warning" : "Error"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!successful)
|
if (!successful)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (CompilerError const& _exception)
|
catch (CompilerError const& _exception)
|
||||||
{
|
{
|
||||||
|
g_hasOutput = true;
|
||||||
formatter.printExceptionInformation(_exception, "Compiler error");
|
formatter.printExceptionInformation(_exception, "Compiler error");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (InternalCompilerError const& _exception)
|
catch (InternalCompilerError const& _exception)
|
||||||
{
|
{
|
||||||
cerr << "Internal compiler error during compilation:" << endl
|
serr() << "Internal compiler error during compilation:" << endl
|
||||||
<< boost::diagnostic_information(_exception);
|
<< boost::diagnostic_information(_exception);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (UnimplementedFeatureError const& _exception)
|
catch (UnimplementedFeatureError const& _exception)
|
||||||
{
|
{
|
||||||
cerr << "Unimplemented feature:" << endl
|
serr() << "Unimplemented feature:" << endl
|
||||||
<< boost::diagnostic_information(_exception);
|
<< boost::diagnostic_information(_exception);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (Error const& _error)
|
catch (Error const& _error)
|
||||||
{
|
{
|
||||||
if (_error.type() == Error::Type::DocstringParsingError)
|
if (_error.type() == Error::Type::DocstringParsingError)
|
||||||
cerr << "Documentation parsing error: " << *boost::get_error_info<errinfo_comment>(_error) << endl;
|
serr() << "Documentation parsing error: " << *boost::get_error_info<errinfo_comment>(_error) << endl;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
g_hasOutput = true;
|
||||||
formatter.printExceptionInformation(_error, _error.typeName());
|
formatter.printExceptionInformation(_error, _error.typeName());
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (Exception const& _exception)
|
catch (Exception const& _exception)
|
||||||
{
|
{
|
||||||
cerr << "Exception during compilation: " << boost::diagnostic_information(_exception) << endl;
|
serr() << "Exception during compilation: " << boost::diagnostic_information(_exception) << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
cerr << "Unknown exception during compilation." << endl;
|
serr() << "Unknown exception during compilation." << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -972,7 +997,7 @@ void CommandLineInterface::handleCombinedJSON()
|
|||||||
if (m_args.count(g_argOutputDir))
|
if (m_args.count(g_argOutputDir))
|
||||||
createJson("combined", json);
|
createJson("combined", json);
|
||||||
else
|
else
|
||||||
cout << json << endl;
|
sout() << json << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandLineInterface::handleAst(string const& _argStr)
|
void CommandLineInterface::handleAst(string const& _argStr)
|
||||||
@ -1028,10 +1053,10 @@ void CommandLineInterface::handleAst(string const& _argStr)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << title << endl << endl;
|
sout() << title << endl << endl;
|
||||||
for (auto const& sourceCode: m_sourceCodes)
|
for (auto const& sourceCode: m_sourceCodes)
|
||||||
{
|
{
|
||||||
cout << endl << "======= " << sourceCode.first << " =======" << endl;
|
sout() << endl << "======= " << sourceCode.first << " =======" << endl;
|
||||||
if (_argStr == g_argAst)
|
if (_argStr == g_argAst)
|
||||||
{
|
{
|
||||||
ASTPrinter printer(
|
ASTPrinter printer(
|
||||||
@ -1039,10 +1064,10 @@ void CommandLineInterface::handleAst(string const& _argStr)
|
|||||||
sourceCode.second,
|
sourceCode.second,
|
||||||
gasCosts
|
gasCosts
|
||||||
);
|
);
|
||||||
printer.print(cout);
|
printer.print(sout());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ASTJsonConverter(legacyFormat, m_compiler->sourceIndices()).print(cout, m_compiler->ast(sourceCode.first));
|
ASTJsonConverter(legacyFormat, m_compiler->sourceIndices()).print(sout(), m_compiler->ast(sourceCode.first));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1090,7 +1115,7 @@ bool CommandLineInterface::link()
|
|||||||
if (it == end) break;
|
if (it == end) break;
|
||||||
if (end - it < placeholderSize)
|
if (end - it < placeholderSize)
|
||||||
{
|
{
|
||||||
cerr << "Error in binary object file " << src.first << " at position " << (end - src.second.begin()) << endl;
|
serr() << "Error in binary object file " << src.first << " at position " << (end - src.second.begin()) << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1101,7 +1126,7 @@ bool CommandLineInterface::link()
|
|||||||
copy(hexStr.begin(), hexStr.end(), it);
|
copy(hexStr.begin(), hexStr.end(), it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cerr << "Reference \"" << name << "\" in file \"" << src.first << "\" still unresolved." << endl;
|
serr() << "Reference \"" << name << "\" in file \"" << src.first << "\" still unresolved." << endl;
|
||||||
it += placeholderSize;
|
it += placeholderSize;
|
||||||
}
|
}
|
||||||
// Remove hints for resolved libraries.
|
// Remove hints for resolved libraries.
|
||||||
@ -1117,17 +1142,18 @@ void CommandLineInterface::writeLinkedFiles()
|
|||||||
{
|
{
|
||||||
for (auto const& src: m_sourceCodes)
|
for (auto const& src: m_sourceCodes)
|
||||||
if (src.first == g_stdinFileName)
|
if (src.first == g_stdinFileName)
|
||||||
cout << src.second << endl;
|
sout() << src.second << endl;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ofstream outFile(src.first);
|
ofstream outFile(src.first);
|
||||||
outFile << src.second;
|
outFile << src.second;
|
||||||
if (!outFile)
|
if (!outFile)
|
||||||
{
|
{
|
||||||
cerr << "Could not write to file " << src.first << ". Aborting." << endl;
|
serr() << "Could not write to file " << src.first << ". Aborting." << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sout() << "Linking completed." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
string CommandLineInterface::libraryPlaceholderHint(string const& _libraryName)
|
string CommandLineInterface::libraryPlaceholderHint(string const& _libraryName)
|
||||||
@ -1164,12 +1190,12 @@ bool CommandLineInterface::assemble(
|
|||||||
}
|
}
|
||||||
catch (Exception const& _exception)
|
catch (Exception const& _exception)
|
||||||
{
|
{
|
||||||
cerr << "Exception in assembler: " << boost::diagnostic_information(_exception) << endl;
|
serr() << "Exception in assembler: " << boost::diagnostic_information(_exception) << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
cerr << "Unknown exception in assembler." << endl;
|
serr() << "Unknown exception in assembler." << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1178,13 +1204,16 @@ bool CommandLineInterface::assemble(
|
|||||||
{
|
{
|
||||||
auto const& stack = sourceAndStack.second;
|
auto const& stack = sourceAndStack.second;
|
||||||
auto scannerFromSourceName = [&](string const&) -> Scanner const& { return stack.scanner(); };
|
auto scannerFromSourceName = [&](string const&) -> Scanner const& { return stack.scanner(); };
|
||||||
SourceReferenceFormatter formatter(cerr, scannerFromSourceName);
|
SourceReferenceFormatter formatter(serr(false), scannerFromSourceName);
|
||||||
|
|
||||||
for (auto const& error: stack.errors())
|
for (auto const& error: stack.errors())
|
||||||
|
{
|
||||||
|
g_hasOutput = true;
|
||||||
formatter.printExceptionInformation(
|
formatter.printExceptionInformation(
|
||||||
*error,
|
*error,
|
||||||
(error->type() == Error::Type::Warning) ? "Warning" : "Error"
|
(error->type() == Error::Type::Warning) ? "Warning" : "Error"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
if (!Error::containsOnlyWarnings(stack.errors()))
|
if (!Error::containsOnlyWarnings(stack.errors()))
|
||||||
successful = false;
|
successful = false;
|
||||||
}
|
}
|
||||||
@ -1198,11 +1227,11 @@ bool CommandLineInterface::assemble(
|
|||||||
_targetMachine == AssemblyStack::Machine::EVM ? "EVM" :
|
_targetMachine == AssemblyStack::Machine::EVM ? "EVM" :
|
||||||
_targetMachine == AssemblyStack::Machine::EVM15 ? "EVM 1.5" :
|
_targetMachine == AssemblyStack::Machine::EVM15 ? "EVM 1.5" :
|
||||||
"eWasm";
|
"eWasm";
|
||||||
cout << endl << "======= " << src.first << " (" << machine << ") =======" << endl;
|
sout() << endl << "======= " << src.first << " (" << machine << ") =======" << endl;
|
||||||
AssemblyStack& stack = assemblyStacks[src.first];
|
AssemblyStack& stack = assemblyStacks[src.first];
|
||||||
|
|
||||||
cout << endl << "Pretty printed source:" << endl;
|
sout() << endl << "Pretty printed source:" << endl;
|
||||||
cout << stack.print() << endl;
|
sout() << stack.print() << endl;
|
||||||
|
|
||||||
MachineAssemblyObject object;
|
MachineAssemblyObject object;
|
||||||
try
|
try
|
||||||
@ -1211,26 +1240,26 @@ bool CommandLineInterface::assemble(
|
|||||||
}
|
}
|
||||||
catch (Exception const& _exception)
|
catch (Exception const& _exception)
|
||||||
{
|
{
|
||||||
cerr << "Exception while assembling: " << boost::diagnostic_information(_exception) << endl;
|
serr() << "Exception while assembling: " << boost::diagnostic_information(_exception) << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
cerr << "Unknown exception while assembling." << endl;
|
serr() << "Unknown exception while assembling." << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << endl << "Binary representation:" << endl;
|
sout() << endl << "Binary representation:" << endl;
|
||||||
if (object.bytecode)
|
if (object.bytecode)
|
||||||
cout << object.bytecode->toHex() << endl;
|
sout() << object.bytecode->toHex() << endl;
|
||||||
else
|
else
|
||||||
cerr << "No binary representation found." << endl;
|
serr() << "No binary representation found." << endl;
|
||||||
|
|
||||||
cout << endl << "Text representation:" << endl;
|
sout() << endl << "Text representation:" << endl;
|
||||||
if (!object.assembly.empty())
|
if (!object.assembly.empty())
|
||||||
cout << object.assembly << endl;
|
sout() << object.assembly << endl;
|
||||||
else
|
else
|
||||||
cerr << "No text representation found." << endl;
|
serr() << "No text representation found." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1249,7 +1278,7 @@ void CommandLineInterface::outputCompilationResults()
|
|||||||
for (string const& contract: contracts)
|
for (string const& contract: contracts)
|
||||||
{
|
{
|
||||||
if (needsHumanTargetedStdout(m_args))
|
if (needsHumanTargetedStdout(m_args))
|
||||||
cout << endl << "======= " << contract << " =======" << endl;
|
sout() << endl << "======= " << contract << " =======" << endl;
|
||||||
|
|
||||||
// do we need EVM assembly?
|
// do we need EVM assembly?
|
||||||
if (m_args.count(g_argAsm) || m_args.count(g_argAsmJson))
|
if (m_args.count(g_argAsm) || m_args.count(g_argAsmJson))
|
||||||
@ -1266,7 +1295,7 @@ void CommandLineInterface::outputCompilationResults()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "EVM assembly:" << endl << ret << endl;
|
sout() << "EVM assembly:" << endl << ret << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1280,6 +1309,14 @@ void CommandLineInterface::outputCompilationResults()
|
|||||||
handleNatspec(true, contract);
|
handleNatspec(true, contract);
|
||||||
handleNatspec(false, contract);
|
handleNatspec(false, contract);
|
||||||
} // end of contracts iteration
|
} // end of contracts iteration
|
||||||
|
|
||||||
|
if (!g_hasOutput)
|
||||||
|
{
|
||||||
|
if (m_args.count(g_argOutputDir))
|
||||||
|
sout() << "Compiler run successful. Artifact(s) can be found in directory " << m_args.at(g_argOutputDir).as<string>() << "." << endl;
|
||||||
|
else
|
||||||
|
serr() << "Compiler run successful, no output requested." << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user