@@ -121,48 +121,29 @@ void CommandLineInterface::handleBinary(string const& _contract)
121
121
if (m_args.count (g_argBinaryStr))
122
122
{
123
123
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)));
129
125
else
130
126
{
131
127
cout << " Binary: " << endl;
132
128
cout << toHex (m_compiler->getBytecode (_contract)) << endl;
133
129
}
134
-
135
130
}
136
131
if (m_args.count (g_argCloneBinaryStr))
137
132
{
138
133
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)));
144
135
else
145
136
{
146
137
cout << " Clone Binary: " << endl;
147
138
cout << toHex (m_compiler->getCloneBytecode (_contract)) << endl;
148
139
}
149
140
}
150
- else
151
- {
152
- cout << " Binary: " << endl;
153
- cout << toHex (m_compiler->getBytecode (_contract)) << endl;
154
- }
155
-
156
141
}
157
142
158
143
void CommandLineInterface::handleOpcode (string const & _contract)
159
144
{
160
145
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)));
166
147
else
167
148
{
168
149
cout << " Opcodes: " << endl;
@@ -190,11 +171,7 @@ void CommandLineInterface::handleSignatureHashes(string const& _contract)
190
171
out += toHex (it.first .ref ()) + " : " + it.second ->externalSignature () + " \n " ;
191
172
192
173
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);
198
175
else
199
176
cout << " Function signatures: " << endl << out;
200
177
}
@@ -234,11 +211,7 @@ void CommandLineInterface::handleMeta(DocumentationType _type, string const& _co
234
211
if (m_args.count (argName))
235
212
{
236
213
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));
242
215
else
243
216
{
244
217
cout << title << endl;
@@ -301,74 +274,86 @@ void CommandLineInterface::createFile(string const& _fileName, string const& _da
301
274
{
302
275
namespace fs = boost::filesystem;
303
276
// 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>());
305
278
fs::create_directories (p);
306
- ofstream outFile ((p / _fileName).string ());
279
+ string pathName = (p / _fileName).string ();
280
+ ofstream outFile (pathName);
307
281
outFile << _data;
308
282
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 ));
310
284
}
311
285
312
286
bool CommandLineInterface::parseArguments (int _argc, char ** _argv)
313
287
{
314
288
// 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 );
316
300
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
+ )
324
315
(
325
316
" combined-json" ,
326
317
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."
328
319
)
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" );
342
339
343
340
// All positional options should be interpreted as input files
344
341
po::positional_options_description filesPositions;
345
- filesPositions.add (" output-dir" , 1 );
346
342
filesPositions.add (" input-file" , -1 );
347
343
348
344
// parse the compiler arguments
349
345
try
350
346
{
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);
353
350
}
354
351
catch (po::error const & _exception)
355
352
{
356
353
cerr << _exception.what () << endl;
357
354
return false ;
358
355
}
359
356
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
-
372
357
if (m_args.count (" help" ))
373
358
{
374
359
cout << desc;
@@ -381,6 +366,18 @@ bool CommandLineInterface::parseArguments(int _argc, char** _argv)
381
366
return false ;
382
367
}
383
368
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
+
384
381
return true ;
385
382
}
386
383
@@ -414,13 +411,13 @@ bool CommandLineInterface::processInput()
414
411
m_sourceCodes[infile] = dev::contentsString (infile);
415
412
}
416
413
417
- m_compiler.reset (new CompilerStack (m_args[ " add-std " ]. as < bool >() ));
414
+ m_compiler.reset (new CompilerStack (m_args. count (g_argAddStandard) > 0 ));
418
415
try
419
416
{
420
417
for (auto const & sourceCode: m_sourceCodes)
421
418
m_compiler->addSource (sourceCode.first , sourceCode.second );
422
419
// TODO: Perhaps we should not compile unless requested
423
- bool optimize = m_args[ " optimize" ]. as < bool >() ;
420
+ bool optimize = m_args. count ( " optimize" ) > 0 ;
424
421
unsigned runs = m_args[" optimize-runs" ].as <unsigned >();
425
422
m_compiler->compile (optimize, runs);
426
423
}
@@ -561,7 +558,8 @@ void CommandLineInterface::handleAst(string const& _argStr)
561
558
converter.print (data);
562
559
postfix += " _json" ;
563
560
}
564
- createFile (sourceCode.first + postfix + " .ast" , data.str ());
561
+ boost::filesystem::path path (sourceCode.first );
562
+ createFile (path.filename ().string () + postfix + " .ast" , data.str ());
565
563
}
566
564
}
567
565
else
0 commit comments