Styling issues and new class name for the CLI

This commit is contained in:
Lefteris Karapetsas 2014-12-09 17:39:34 +01:00
parent 5ab37de94a
commit df82e26d5a
3 changed files with 98 additions and 111 deletions

View File

@ -17,9 +17,9 @@
/** /**
* @author Lefteris <lefteris@ethdev.com> * @author Lefteris <lefteris@ethdev.com>
* @date 2014 * @date 2014
* Solidity compiler context class. * Solidity command line interface.
*/ */
#include "SolContext.h" #include "CommandLineInterface.h"
#include <string> #include <string>
#include <iostream> #include <iostream>
@ -69,15 +69,14 @@ static bool needStdout(po::variables_map const& _args)
static inline bool outputToFile(OutputType type) static inline bool outputToFile(OutputType type)
{ {
return type == OutputType::FILE || type == OutputType::BOTH; return type == OutputType::FILE || type == OutputType::BOTH;
} }
static inline bool outputToStdout(OutputType type) static inline bool outputToStdout(OutputType type)
{ {
return type == OutputType::STDOUT || type == OutputType::BOTH; return type == OutputType::STDOUT || type == OutputType::BOTH;
} }
static std::istream& operator>>(std::istream& _in, OutputType& io_output) static std::istream& operator>>(std::istream& _in, OutputType& io_output)
{ {
std::string token; std::string token;
@ -93,10 +92,10 @@ static std::istream& operator>>(std::istream& _in, OutputType& io_output)
return _in; return _in;
} }
void SolContext::handleBytecode(string const& _argName, void CommandLineInterface::handleBytecode(string const& _argName,
string const& _title, string const& _title,
string const& _contract, string const& _contract,
string const& _suffix) string const& _suffix)
{ {
if (m_args.count(_argName)) if (m_args.count(_argName))
{ {
@ -105,8 +104,8 @@ void SolContext::handleBytecode(string const& _argName,
{ {
cout << _title << endl; cout << _title << endl;
if (_suffix == "opcodes") if (_suffix == "opcodes")
; ;
// TODO: Figure out why after moving to own class ostream operator does not work for vector of bytes // TODO: Figure out why after moving to own class ostream operator does not work for vector of bytes
// cout << m_compiler.getBytecode(_contract) << endl; // cout << m_compiler.getBytecode(_contract) << endl;
else else
cout << toHex(m_compiler.getBytecode(_contract)) << endl; cout << toHex(m_compiler.getBytecode(_contract)) << endl;
@ -116,8 +115,8 @@ void SolContext::handleBytecode(string const& _argName,
{ {
ofstream outFile(_contract + _suffix); ofstream outFile(_contract + _suffix);
if (_suffix == "opcodes") if (_suffix == "opcodes")
; ;
// TODO: Figure out why after moving to own class ostream operator does not work for vector of bytes // TODO: Figure out why after moving to own class ostream operator does not work for vector of bytes
// outFile << m_compiler.getBytecode(_contract); // outFile << m_compiler.getBytecode(_contract);
else else
outFile << toHex(m_compiler.getBytecode(_contract)); outFile << toHex(m_compiler.getBytecode(_contract));
@ -126,8 +125,8 @@ void SolContext::handleBytecode(string const& _argName,
} }
} }
void SolContext::handleJson(DocumentationType _type, void CommandLineInterface::handleJson(DocumentationType _type,
string const& _contract) string const& _contract)
{ {
std::string argName; std::string argName;
std::string suffix; std::string suffix;
@ -172,76 +171,67 @@ void SolContext::handleJson(DocumentationType _type,
} }
} }
bool CommandLineInterface::parseArguments(int argc, char** argv)
bool SolContext::parseArguments(int argc, char** argv)
{ {
#define OUTPUT_TYPE_STR "Legal values:\n" \ #define OUTPUT_TYPE_STR "Legal values:\n" \
"\tstdout: Print it to standard output\n" \ "\tstdout: Print it to standard output\n" \
"\tfile: Print it to a file with same name\n" \ "\tfile: Print it to a file with same name\n" \
"\tboth: Print both to a file and the stdout\n" "\tboth: Print both to a file and the stdout\n"
// Declare the supported options. // Declare the supported options.
po::options_description desc("Allowed options"); po::options_description desc("Allowed options");
desc.add_options() desc.add_options()
("help", "Show help message and exit") ("help", "Show help message and exit")
("version", "Show version and exit") ("version", "Show version and exit")
("optimize", po::value<bool>()->default_value(false), "Optimize bytecode for size") ("optimize", po::value<bool>()->default_value(false), "Optimize bytecode for size")
("input-file", po::value<vector<string>>(), "input file") ("input-file", po::value<vector<string>>(), "input file")
("ast", po::value<OutputType>(), ("ast", po::value<OutputType>(),
"Request to output the AST of the contract. " OUTPUT_TYPE_STR) "Request to output the AST of the contract. " OUTPUT_TYPE_STR)
("asm", po::value<OutputType>(), ("asm", po::value<OutputType>(),
"Request to output the EVM assembly of the contract. " OUTPUT_TYPE_STR) "Request to output the EVM assembly of the contract. " OUTPUT_TYPE_STR)
("opcodes", po::value<OutputType>(), ("opcodes", po::value<OutputType>(),
"Request to output the Opcodes of the contract. " OUTPUT_TYPE_STR) "Request to output the Opcodes of the contract. " OUTPUT_TYPE_STR)
("binary", po::value<OutputType>(), ("binary", po::value<OutputType>(),
"Request to output the contract in binary (hexadecimal). " OUTPUT_TYPE_STR) "Request to output the contract in binary (hexadecimal). " OUTPUT_TYPE_STR)
("abi", po::value<OutputType>(), ("abi", po::value<OutputType>(),
"Request to output the contract's ABI interface. " OUTPUT_TYPE_STR) "Request to output the contract's ABI interface. " OUTPUT_TYPE_STR)
("natspec-user", po::value<OutputType>(), ("natspec-user", po::value<OutputType>(),
"Request to output the contract's Natspec user documentation. " OUTPUT_TYPE_STR) "Request to output the contract's Natspec user documentation. " OUTPUT_TYPE_STR)
("natspec-dev", po::value<OutputType>(), ("natspec-dev", po::value<OutputType>(),
"Request to output the contract's Natspec developer documentation. " OUTPUT_TYPE_STR); "Request to output the contract's Natspec developer documentation. " OUTPUT_TYPE_STR);
#undef OUTPUT_TYPE_STR #undef OUTPUT_TYPE_STR
// All positional options should be interpreted as input files // All positional options should be interpreted as input files
po::positional_options_description p; po::positional_options_description p;
p.add("input-file", -1); p.add("input-file", -1);
// parse the compiler arguments // parse the compiler arguments
try try
{ {
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).allow_unregistered().run(), m_args); po::store(po::command_line_parser(argc, argv).options(desc).positional(p).allow_unregistered().run(), m_args);
} }
catch (po::error const& exception) catch (po::error const& exception)
{ {
cout << exception.what() << endl; cout << exception.what() << endl;
return false; return false;
} }
po::notify(m_args); po::notify(m_args);
if (m_args.count("help")) if (m_args.count("help"))
{ {
cout << desc; cout << desc;
return false; return false;
} }
if (m_args.count("version")) if (m_args.count("version"))
{ {
version(); version();
return false; return false;
} }
return true; return true;
} }
bool SolContext::processInput() bool CommandLineInterface::processInput()
{ {
if (!m_args.count("input-file")) if (!m_args.count("input-file"))
{ {
@ -260,7 +250,7 @@ bool SolContext::processInput()
{ {
for (auto const& sourceCode: m_sourceCodes) for (auto const& sourceCode: m_sourceCodes)
m_compiler.addSource(sourceCode.first, sourceCode.second); m_compiler.addSource(sourceCode.first, sourceCode.second);
// TODO: Perhaps we should not compile unless requested // TODO: Perhaps we should not compile unless requested
m_compiler.compile(m_args["optimize"].as<bool>()); m_compiler.compile(m_args["optimize"].as<bool>());
} }
catch (ParserError const& exception) catch (ParserError const& exception)
@ -299,10 +289,10 @@ bool SolContext::processInput()
return false; return false;
} }
return true; return true;
} }
void SolContext::actOnInput() void CommandLineInterface::actOnInput()
{ {
// do we need AST output? // do we need AST output?
if (m_args.count("ast")) if (m_args.count("ast"))
@ -342,13 +332,13 @@ void SolContext::actOnInput()
if (m_args.count("asm")) if (m_args.count("asm"))
{ {
auto choice = m_args["asm"].as<OutputType>(); auto choice = m_args["asm"].as<OutputType>();
if (outputToStdout(choice)) if (outputToStdout(choice))
{ {
cout << "EVM assembly:" << endl; cout << "EVM assembly:" << endl;
m_compiler.streamAssembly(cout, contract); m_compiler.streamAssembly(cout, contract);
} }
if (outputToFile(choice)) if (outputToFile(choice))
{ {
ofstream outFile(contract + ".evm"); ofstream outFile(contract + ".evm");
m_compiler.streamAssembly(outFile, contract); m_compiler.streamAssembly(outFile, contract);

View File

@ -17,7 +17,7 @@
/** /**
* @author Lefteris <lefteris@ethdev.com> * @author Lefteris <lefteris@ethdev.com>
* @date 2014 * @date 2014
* Solidity compiler context class. * Solidity command line interface.
*/ */
#pragma once #pragma once
@ -40,32 +40,32 @@ enum class OutputType: uint8_t
BOTH BOTH
}; };
class SolContext class CommandLineInterface
{ {
public: public:
SolContext() {} CommandLineInterface() {}
/// Parse command line arguments and return false if we should not continue /// Parse command line arguments and return false if we should not continue
bool parseArguments(int argc, char** argv); bool parseArguments(int argc, char** argv);
/// Parse the files and create source code objects /// Parse the files and create source code objects
bool processInput(); bool processInput();
/// Perform actions on the input depending on provided compiler arguments /// Perform actions on the input depending on provided compiler arguments
void actOnInput(); void actOnInput();
private: private:
void handleBytecode(std::string const& _argName, void handleBytecode(std::string const& _argName,
std::string const& _title, std::string const& _title,
std::string const& _contract, std::string const& _contract,
std::string const& _suffix); std::string const& _suffix);
void handleJson(DocumentationType _type, void handleJson(DocumentationType _type,
std::string const& _contract); std::string const& _contract);
/// Compiler arguments variable map /// Compiler arguments variable map
boost::program_options::variables_map m_args; boost::program_options::variables_map m_args;
/// map of input files to source code strings /// map of input files to source code strings
std::map<std::string, std::string> m_sourceCodes; std::map<std::string, std::string> m_sourceCodes;
/// Solidity compiler stack /// Solidity compiler stack
dev::solidity::CompilerStack m_compiler; dev::solidity::CompilerStack m_compiler;
}; };
} }

View File

@ -20,19 +20,16 @@
* Solidity commandline compiler. * Solidity commandline compiler.
*/ */
#include "CommandLineInterface.h"
#include "SolContext.h"
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
dev::solidity::SolContext ctx; dev::solidity::CommandLineInterface cli;
if (!ctx.parseArguments(argc, argv)) if (!cli.parseArguments(argc, argv))
return 1; return 1;
if (!ctx.processInput()) if (!cli.processInput())
return 1; return 1;
ctx.actOnInput(); cli.actOnInput();
return 0; return 0;
} }