@@ -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
158143void 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
312286bool 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
0 commit comments