Skip to content

Commit

Permalink
CommandLineInterface: Update control flow to accommodate the new way …
Browse files Browse the repository at this point in the history
…of reporting errors
  • Loading branch information
cameel committed Nov 9, 2021
1 parent e829bcd commit c8380c2
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 158 deletions.
70 changes: 36 additions & 34 deletions solc/CommandLineInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ void CommandLineInterface::handleGasEstimation(string const& _contract)
}
}

bool CommandLineInterface::readInputFiles()
void CommandLineInterface::readInputFiles()
{
solAssert(!m_standardJsonInput.has_value(), "");

Expand All @@ -413,7 +413,7 @@ bool CommandLineInterface::readInputFiles()
m_options.input.mode == InputMode::License ||
m_options.input.mode == InputMode::Version
)
return true;
return;

m_fileReader.setBasePath(m_options.input.basePath);

Expand Down Expand Up @@ -501,8 +501,6 @@ bool CommandLineInterface::readInputFiles()

if (m_fileReader.sourceCodes().empty() && !m_standardJsonInput.has_value())
solThrow(CommandLineValidationError, "All specified input files either do not exist or are not regular files.");

return true;
}

map<string, Json::Value> CommandLineInterface::parseAstFromInput()
Expand Down Expand Up @@ -568,6 +566,30 @@ void CommandLineInterface::createJson(string const& _fileName, string const& _js
createFile(boost::filesystem::basename(_fileName) + string(".json"), _json);
}

bool CommandLineInterface::run(int _argc, char const* const* _argv)
{
try
{
if (!parseArguments(_argc, _argv))
return false;

readInputFiles();
processInput();
return true;
}
catch (CommandLineError const& _exception)
{
m_hasOutput = true;

// There might be no message in the exception itself if the error output is bulky and has
// already been printed to stderr (this happens e.g. for compiler errors).
if (_exception.what() != ""s)
serr() << _exception.what() << endl;

return false;
}
}

bool CommandLineInterface::parseArguments(int _argc, char const* const* _argv)
{
CommandLineParser parser;
Expand All @@ -581,22 +603,13 @@ bool CommandLineInterface::parseArguments(int _argc, char const* const* _argv)
return false;
}

try
{
parser.parse(_argc, _argv);
}
catch (CommandLineValidationError const& _exception)
{
serr() << _exception.what() << endl;
return false;
}

parser.parse(_argc, _argv);
m_options = parser.options();

return true;
}

bool CommandLineInterface::processInput()
void CommandLineInterface::processInput()
{
switch (m_options.input.mode)
{
Expand All @@ -619,18 +632,15 @@ bool CommandLineInterface::processInput()
break;
}
case InputMode::Assembler:
if (!assemble(m_options.assembly.inputLanguage, m_options.assembly.targetMachine))
return false;
assemble(m_options.assembly.inputLanguage, m_options.assembly.targetMachine);
break;
case InputMode::Linker:
if (!link())
return false;
link();
writeLinkedFiles();
break;
case InputMode::Compiler:
case InputMode::CompilerWithASTImport:
if (!compile())
return false;
compile();
outputCompilationResults();
}

Expand All @@ -651,7 +661,7 @@ void CommandLineInterface::printLicense()
sout() << licenseText << endl;
}

bool CommandLineInterface::compile()
void CommandLineInterface::compile()
{
solAssert(m_options.input.mode == InputMode::Compiler || m_options.input.mode == InputMode::CompilerWithASTImport, "");

Expand Down Expand Up @@ -714,6 +724,8 @@ bool CommandLineInterface::compile()
}
catch (Exception const& _exc)
{
// FIXME: AST import is missing proper validations. This hack catches failing
// assertions and presents them as if they were compiler errors.
solThrow(CommandLineExecutionError, "Failed to import AST: "s + _exc.what());
}
}
Expand Down Expand Up @@ -754,8 +766,6 @@ bool CommandLineInterface::compile()
solThrow(CommandLineExecutionError, "");
}
}

return true;
}

void CommandLineInterface::handleCombinedJSON()
Expand Down Expand Up @@ -884,7 +894,7 @@ void CommandLineInterface::handleAst()
}
}

bool CommandLineInterface::link()
void CommandLineInterface::link()
{
solAssert(m_options.input.mode == InputMode::Linker, "");

Expand Down Expand Up @@ -945,8 +955,6 @@ bool CommandLineInterface::link()
src.second.resize(src.second.size() - 1);
}
m_fileReader.setSources(move(sourceCodes));

return true;
}

void CommandLineInterface::writeLinkedFiles()
Expand Down Expand Up @@ -986,7 +994,7 @@ string CommandLineInterface::objectWithLinkRefsHex(evmasm::LinkerObject const& _
return out;
}

bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul::AssemblyStack::Machine _targetMachine)
void CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul::AssemblyStack::Machine _targetMachine)
{
solAssert(m_options.input.mode == InputMode::Assembler, "");

Expand Down Expand Up @@ -1090,8 +1098,6 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul:
serr() << "No text representation found." << endl;
}
}

return true;
}

void CommandLineInterface::outputCompilationResults()
Expand Down Expand Up @@ -1128,13 +1134,9 @@ void CommandLineInterface::outputCompilationResults()
ret = m_compiler->assemblyString(contract, m_fileReader.sourceCodes());

if (!m_options.output.dir.empty())
{
createFile(m_compiler->filesystemFriendlyName(contract) + (m_options.compiler.outputs.asmJson ? "_evm.json" : ".evm"), ret);
}
else
{
sout() << "EVM assembly:" << endl << ret << endl;
}
}

if (m_options.compiler.estimateGas)
Expand Down
32 changes: 24 additions & 8 deletions solc/CommandLineInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,28 @@ class CommandLineInterface
m_options(_options)
{}

/// Parse command line arguments and return false if we should not continue
/// Parses command-line arguments, executes the requested operation and handles validation and
/// execution errors.
/// @returns false if it catches a @p CommandLineValidationError or if the application is
/// expected to exit with a non-zero exit code despite there being no error.
bool run(int _argc, char const* const* _argv);

/// Parses command line arguments and stores the result in @p m_options.
/// @throws CommandLineValidationError if command-line arguments are invalid.
/// @returns false if the application is expected to exit with a non-zero exit code despite
/// there being no error.
bool parseArguments(int _argc, char const* const* _argv);
/// Read the content of all input files and initialize the file reader.
bool readInputFiles();
/// Parse the files, create source code objects, print the output.
bool processInput();

/// Reads the content of all input files and initializes the file reader.
/// @throws CommandLineValidationError if it fails to read the input files (invalid paths,
/// non-existent files, not enough or too many input files, etc.).
void readInputFiles();

/// Executes the requested operation (compilation, assembling, standard JSON, etc.) and prints
/// results to the terminal.
/// @throws CommandLineExecutionError if execution fails due to errors in the input files.
/// @throws CommandLineOutputError if creating output files or writing to them fails.
void processInput();

CommandLineOptions const& options() const { return m_options; }
FileReader const& fileReader() const { return m_fileReader; }
Expand All @@ -65,15 +81,15 @@ class CommandLineInterface
private:
void printVersion();
void printLicense();
bool compile();
bool link();
void compile();
void link();
void writeLinkedFiles();
/// @returns the ``// <identifier> -> name`` hint for library placeholders.
static std::string libraryPlaceholderHint(std::string const& _libraryName);
/// @returns the full object with library placeholder hints in hex.
static std::string objectWithLinkRefsHex(evmasm::LinkerObject const& _obj);

bool assemble(yul::AssemblyStack::Language _language, yul::AssemblyStack::Machine _targetMachine);
void assemble(yul::AssemblyStack::Language _language, yul::AssemblyStack::Machine _targetMachine);

void outputCompilationResults();

Expand Down
7 changes: 1 addition & 6 deletions solc/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,7 @@ int main(int argc, char** argv)
{
setDefaultOrCLocale();
solidity::frontend::CommandLineInterface cli(cin, cout, cerr);
bool success =
cli.parseArguments(argc, argv) &&
cli.readInputFiles() &&
cli.processInput();

return success ? 0 : 1;
return cli.run(argc, argv) ? 0 : 1;
}
catch (smtutil::SMTLogicError const& _exception)
{
Expand Down
Loading

0 comments on commit c8380c2

Please sign in to comment.