diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 220f0e393..dbfb46756 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -323,6 +323,16 @@ OptimiserSettings CommandLineOptions::optimiserSettings() const return settings; } +bool CommandLineParser::parse(int _argc, char const* const* _argv, bool _interactiveTerminal) +{ + m_hasOutput = false; + + if (!parseArgs(_argc, _argv, _interactiveTerminal)) + return false; + + return processArgs(); +} + bool CommandLineParser::parseInputPathsAndRemappings() { m_options.input.ignoreMissingFiles = (m_args.count(g_strIgnoreMissingFiles) > 0); @@ -478,10 +488,8 @@ bool CommandLineParser::parseLibraryOption(string const& _input) return true; } -bool CommandLineParser::parse(int _argc, char const* const* _argv, bool interactiveTerminal) +po::options_description CommandLineParser::optionsDescription() { - m_hasOutput = false; - // Declare the supported options. po::options_description desc((R"(solc, the Solidity commandline compiler. @@ -780,12 +788,22 @@ General Information)").c_str(), ; desc.add(smtCheckerOptions); - po::options_description allOptions = desc; - allOptions.add_options()(g_strInputFile.c_str(), po::value>(), "input file"); + desc.add_options()(g_strInputFile.c_str(), po::value>(), "input file"); + return desc; +} +po::positional_options_description CommandLineParser::positionalOptionsDescription() +{ // All positional options should be interpreted as input files po::positional_options_description filesPositions; filesPositions.add(g_strInputFile.c_str(), -1); + return filesPositions; +} + +bool CommandLineParser::parseArgs(int _argc, char const* const* _argv, bool _interactiveTerminal) +{ + po::options_description allOptions = optionsDescription(); + po::positional_options_description filesPositions = positionalOptionsDescription(); // parse the compiler arguments try @@ -801,6 +819,25 @@ General Information)").c_str(), return false; } + if (m_args.count(g_strHelp) || (_interactiveTerminal && _argc == 1)) + { + sout() << allOptions; + return false; + } + + if (m_args.count(g_strVersion)) + printVersionAndExit(); + + if (m_args.count(g_strLicense)) + printLicenseAndExit(); + + po::notify(m_args); + + return true; +} + +bool CommandLineParser::processArgs() +{ if (!checkMutuallyExclusive({g_strColor, g_strNoColor})) return false; @@ -826,18 +863,6 @@ General Information)").c_str(), m_options.formatting.withErrorIds = m_args.count(g_strErrorIds); - if (m_args.count(g_strHelp) || (interactiveTerminal && _argc == 1)) - { - sout() << desc; - return false; - } - - if (m_args.count(g_strVersion)) - printVersionAndExit(); - - if (m_args.count(g_strLicense)) - printLicenseAndExit(); - if (m_args.count(g_strRevertStrings)) { string revertStringsString = m_args[g_strRevertStrings].as(); @@ -895,8 +920,6 @@ General Information)").c_str(), m_options.compiler.estimateGas = (m_args.count(g_strGas) > 0); - po::notify(m_args); - if (m_args.count(g_strBasePath)) m_options.input.basePath = m_args[g_strBasePath].as(); diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index ac80f6f0d..41aaab71b 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -195,7 +195,7 @@ public: /// CommandLineOptions structure has been fully initialized. false if there were errors - in /// this case CommandLineOptions may be only partially filled out. May also return false if /// there is not further processing necessary and the program should just exit. - bool parse(int _argc, char const* const* _argv, bool interactiveTerminal); + bool parse(int _argc, char const* const* _argv, bool _interactiveTerminal); CommandLineOptions const& options() const { return m_options; } @@ -203,6 +203,24 @@ public: bool hasOutput() const { return m_hasOutput; } private: + /// @returns a specification of all named command-line options accepted by the compiler. + /// The object can be used to parse command-line arguments or to generate the help screen. + static boost::program_options::options_description optionsDescription(); + + /// @returns a specification of all positional command-line arguments accepted by the compiler. + /// The object can be used to parse command-line arguments or to generate the help screen. + static boost::program_options::positional_options_description positionalOptionsDescription(); + + /// Uses boost::program_options to parse the command-line arguments and leaves the result in @a m_args. + /// Also handles the arguments that result in information being printed followed by immediate exit. + /// @returns false if parsing fails due to syntactical errors or the arguments not matching the description. + bool parseArgs(int _argc, char const* const* _argv, bool _interactiveTerminal); + + /// Validates parsed arguments stored in @a m_args and fills out the internal CommandLineOptions + /// structure. + /// @return false if there are any validation errors, true otherwise. + bool processArgs(); + /// Parses the value supplied to --combined-json. /// @return false if there are any validation errors, true otherwise. bool parseCombinedJsonOption();