Skip to content

Commit 0906042

Browse files
committed
More information for help screen, some fixes for argument parsing.
1 parent 4c8b220 commit 0906042

File tree

3 files changed

+87
-77
lines changed

3 files changed

+87
-77
lines changed

libsolidity/Version.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ using namespace dev;
2929
using namespace dev::solidity;
3030
using namespace std;
3131

32-
char const* dev::solidity::VersionNumber = "0.1.1";
32+
char const* dev::solidity::VersionNumber = "0.1.2";
3333
extern string const dev::solidity::VersionString =
3434
string(dev::solidity::VersionNumber) +
3535
"-" +

solc/CommandLineInterface.cpp

Lines changed: 73 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -121,48 +121,29 @@ void CommandLineInterface::handleBinary(string const& _contract)
121121
if (m_args.count(g_argBinaryStr))
122122
{
123123
if (m_args.count("output-dir"))
124-
{
125-
stringstream data;
126-
data << toHex(m_compiler->getBytecode(_contract));
127-
createFile(_contract + ".bin", data.str());
128-
}
124+
createFile(_contract + ".bin", toHex(m_compiler->getBytecode(_contract)));
129125
else
130126
{
131127
cout << "Binary: " << endl;
132128
cout << toHex(m_compiler->getBytecode(_contract)) << endl;
133129
}
134-
135130
}
136131
if (m_args.count(g_argCloneBinaryStr))
137132
{
138133
if (m_args.count("output-dir"))
139-
{
140-
stringstream data;
141-
data << toHex(m_compiler->getCloneBytecode(_contract));
142-
createFile(_contract + ".clone_bin", data.str());
143-
}
134+
createFile(_contract + ".clone_bin", toHex(m_compiler->getCloneBytecode(_contract)));
144135
else
145136
{
146137
cout << "Clone Binary: " << endl;
147138
cout << toHex(m_compiler->getCloneBytecode(_contract)) << endl;
148139
}
149140
}
150-
else
151-
{
152-
cout << "Binary: " << endl;
153-
cout << toHex(m_compiler->getBytecode(_contract)) << endl;
154-
}
155-
156141
}
157142

158143
void CommandLineInterface::handleOpcode(string const& _contract)
159144
{
160145
if (m_args.count("output-dir"))
161-
{
162-
stringstream data;
163-
data << eth::disassemble(m_compiler->getBytecode(_contract));
164-
createFile(_contract + ".opcode", data.str());
165-
}
146+
createFile(_contract + ".opcode", eth::disassemble(m_compiler->getBytecode(_contract)));
166147
else
167148
{
168149
cout << "Opcodes: " << endl;
@@ -190,11 +171,7 @@ void CommandLineInterface::handleSignatureHashes(string const& _contract)
190171
out += toHex(it.first.ref()) + ": " + it.second->externalSignature() + "\n";
191172

192173
if (m_args.count("output-dir"))
193-
{
194-
stringstream data;
195-
data << out;
196-
createFile(_contract + ".signatures", data.str());
197-
}
174+
createFile(_contract + ".signatures", out);
198175
else
199176
cout << "Function signatures: " << endl << out;
200177
}
@@ -234,11 +211,7 @@ void CommandLineInterface::handleMeta(DocumentationType _type, string const& _co
234211
if (m_args.count(argName))
235212
{
236213
if (m_args.count("output-dir"))
237-
{
238-
stringstream data;
239-
data << m_compiler->getMetadata(_contract, _type);
240-
createFile(_contract + suffix, data.str());
241-
}
214+
createFile(_contract + suffix, m_compiler->getMetadata(_contract, _type));
242215
else
243216
{
244217
cout << title << endl;
@@ -301,74 +274,86 @@ void CommandLineInterface::createFile(string const& _fileName, string const& _da
301274
{
302275
namespace fs = boost::filesystem;
303276
// create directory if not existent
304-
fs::path p(m_args["output-dir"].as<string>());
277+
fs::path p(m_args.at("output-dir").as<string>());
305278
fs::create_directories(p);
306-
ofstream outFile((p / _fileName).string());
279+
string pathName = (p / _fileName).string();
280+
ofstream outFile(pathName);
307281
outFile << _data;
308282
if (!outFile)
309-
BOOST_THROW_EXCEPTION(FileError() << errinfo_comment("Could not write to file: " + _fileName));
283+
BOOST_THROW_EXCEPTION(FileError() << errinfo_comment("Could not write to file: " + pathName));
310284
}
311285

312286
bool CommandLineInterface::parseArguments(int _argc, char** _argv)
313287
{
314288
// Declare the supported options.
315-
po::options_description desc("Allowed options");
289+
po::options_description desc(
290+
R"(solc, the Solidity commandline compiler.
291+
Usage: solc [options] [input_file...]
292+
Compiles the given Solidity input files (or the standard input if none given) and
293+
outputs the components specified in the options at standard output or in files in
294+
the output directory, if specified.
295+
Example: solc --bin -o /tmp/solcoutput contract.sol
296+
297+
Allowed options)",
298+
po::options_description::m_default_line_length,
299+
po::options_description::m_default_line_length - 23);
316300
desc.add_options()
317-
("help", "Show help message and exit")
318-
("version", "Show version and exit")
319-
("optimize", po::value<bool>()->default_value(false), "Optimize bytecode")
320-
("optimize-runs", po::value<unsigned>()->default_value(200), "Estimated number of contract runs for optimizer.")
321-
("add-std", po::value<bool>()->default_value(false), "Add standard contracts")
322-
("input-file", po::value<vector<string>>(), "input file")
323-
("output-dir,o", po::value<string>(), "Output directory path")
301+
("help", "Show help message and exit.")
302+
("version", "Show version and exit.")
303+
("optimize", "Enable bytecode optimizer.")
304+
(
305+
"optimize-runs",
306+
po::value<unsigned>()->value_name("n")->default_value(200),
307+
"Estimated number of contract runs for optimizer tuning."
308+
)
309+
(g_argAddStandard.c_str(), "Add standard contracts.")
310+
(
311+
"output-dir,o",
312+
po::value<string>()->value_name("path"),
313+
"If given, creates one file per component and contract/file at the specified directory."
314+
)
324315
(
325316
"combined-json",
326317
po::value<string>()->value_name(boost::join(g_combinedJsonArgs, ",")),
327-
"Output a single json document containing the specified information, can be combined."
318+
"Output a single json document containing the specified information."
328319
)
329-
(g_argAstStr.c_str(), "Outputs the AST of the contract.")
330-
(g_argAstJson.c_str(), "Outputs the AST of the contract in JSON format.")
331-
(g_argAsmStr.c_str(), "Outputs the EVM assembly of the contract.")
332-
(g_argAsmJsonStr.c_str(), "Outputs the EVM assembly of the contract in JSON format.")
333-
(g_argOpcodesStr.c_str(), "Outputs the Opcodes of the contract.")
334-
(g_argBinaryStr.c_str(), "Outputs the contract in binary (hexadecimal).")
335-
(g_argCloneBinaryStr.c_str(), "Output the clone contract in binary (hexadecimal).")
336-
(g_argAbiStr.c_str(), "Outputs the contract's JSON ABI interface.")
337-
(g_argSolInterfaceStr.c_str(), "Outputs the contract's Solidity interface.")
338-
(g_argSignatureHashes.c_str(), "Outputs the contract's functions' signature hashes.")
339-
(g_argGas.c_str(), "Outputs an estimate for each function's maximal gas usage.")
340-
(g_argNatspecUserStr.c_str(), "Outputs the contract's Natspec user documentation.")
341-
(g_argNatspecDevStr.c_str(), "Outputs the contract's Natspec developer documentation.");
320+
(g_argGas.c_str(), "Print an estimate of the maximal gas usage for each function.");
321+
po::options_description outputComponents("Output Components");
322+
outputComponents.add_options()
323+
(g_argAstStr.c_str(), "AST of all source files.")
324+
(g_argAstJson.c_str(), "AST of all source files in JSON format.")
325+
(g_argAsmStr.c_str(), "EVM assembly of the contracts.")
326+
(g_argAsmJsonStr.c_str(), "EVM assembly of the contracts in JSON format.")
327+
(g_argOpcodesStr.c_str(), "Opcodes of the contracts.")
328+
(g_argBinaryStr.c_str(), "Binary of the contracts in hex.")
329+
(g_argCloneBinaryStr.c_str(), "Binary of the clone contracts in hex.")
330+
(g_argAbiStr.c_str(), "ABI specification of the contracts.")
331+
(g_argSolInterfaceStr.c_str(), "Solidity interface of the contracts.")
332+
(g_argSignatureHashes.c_str(), "Function signature hashes of the contracts.")
333+
(g_argNatspecUserStr.c_str(), "Natspec user documentation of all contracts.")
334+
(g_argNatspecDevStr.c_str(), "Natspec developer documentation of all contracts.");
335+
desc.add(outputComponents);
336+
337+
po::options_description allOptions = desc;
338+
allOptions.add_options()("input-file", po::value<vector<string>>(), "input file");
342339

343340
// All positional options should be interpreted as input files
344341
po::positional_options_description filesPositions;
345-
filesPositions.add("output-dir", 1);
346342
filesPositions.add("input-file", -1);
347343

348344
// parse the compiler arguments
349345
try
350346
{
351-
po::store(po::command_line_parser(_argc, _argv).options(desc).positional(filesPositions).allow_unregistered().run(), m_args);
352-
347+
po::command_line_parser cmdLineParser(_argc, _argv);
348+
cmdLineParser.options(allOptions).positional(filesPositions).allow_unregistered();
349+
po::store(cmdLineParser.run(), m_args);
353350
}
354351
catch (po::error const& _exception)
355352
{
356353
cerr << _exception.what() << endl;
357354
return false;
358355
}
359356

360-
if (m_args.count("combined-json"))
361-
{
362-
vector<string> requests;
363-
for (string const& item: boost::split(requests, m_args["combined-json"].as<string>(), boost::is_any_of(",")))
364-
if (!g_combinedJsonArgs.count(item))
365-
{
366-
cerr << "Invalid option to --combined-json: " << item << endl;
367-
return false;
368-
}
369-
}
370-
po::notify(m_args);
371-
372357
if (m_args.count("help"))
373358
{
374359
cout << desc;
@@ -381,6 +366,18 @@ bool CommandLineInterface::parseArguments(int _argc, char** _argv)
381366
return false;
382367
}
383368

369+
if (m_args.count("combined-json"))
370+
{
371+
vector<string> requests;
372+
for (string const& item: boost::split(requests, m_args["combined-json"].as<string>(), boost::is_any_of(",")))
373+
if (!g_combinedJsonArgs.count(item))
374+
{
375+
cerr << "Invalid option to --combined-json: " << item << endl;
376+
return false;
377+
}
378+
}
379+
po::notify(m_args);
380+
384381
return true;
385382
}
386383

@@ -414,13 +411,13 @@ bool CommandLineInterface::processInput()
414411
m_sourceCodes[infile] = dev::contentsString(infile);
415412
}
416413

417-
m_compiler.reset(new CompilerStack(m_args["add-std"].as<bool>()));
414+
m_compiler.reset(new CompilerStack(m_args.count(g_argAddStandard) > 0));
418415
try
419416
{
420417
for (auto const& sourceCode: m_sourceCodes)
421418
m_compiler->addSource(sourceCode.first, sourceCode.second);
422419
// TODO: Perhaps we should not compile unless requested
423-
bool optimize = m_args["optimize"].as<bool>();
420+
bool optimize = m_args.count("optimize") > 0;
424421
unsigned runs = m_args["optimize-runs"].as<unsigned>();
425422
m_compiler->compile(optimize, runs);
426423
}
@@ -561,7 +558,8 @@ void CommandLineInterface::handleAst(string const& _argStr)
561558
converter.print(data);
562559
postfix += "_json";
563560
}
564-
createFile(sourceCode.first + postfix + ".ast", data.str());
561+
boost::filesystem::path path(sourceCode.first);
562+
createFile(path.filename().string() + postfix + ".ast", data.str());
565563
}
566564
}
567565
else

solc/main.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
*/
2222

2323
#include "CommandLineInterface.h"
24+
#include <iostream>
25+
#include <boost/exception/all.hpp>
26+
27+
using namespace std;
2428

2529
int main(int argc, char** argv)
2630
{
@@ -29,7 +33,15 @@ int main(int argc, char** argv)
2933
return 1;
3034
if (!cli.processInput())
3135
return 1;
32-
cli.actOnInput();
36+
try
37+
{
38+
cli.actOnInput();
39+
}
40+
catch (boost::exception const& _exception)
41+
{
42+
cerr << "Exception during output generation: " << boost::diagnostic_information(_exception) << endl;
43+
return 1;
44+
}
3345

3446
return 0;
3547
}

0 commit comments

Comments
 (0)