@@ -3,6 +3,7 @@ This is a generic main that can be used with any plugin and a
33PSet script. See notes in EventProcessor.cpp for details about it.
44----------------------------------------------------------------------*/
55
6+ #include " FWCore/Framework/interface/CmsRunParser.h"
67#include " FWCore/Framework/interface/EventProcessor.h"
78#include " FWCore/Framework/interface/defaultCmsRunServices.h"
89#include " FWCore/MessageLogger/interface/ExceptionMessages.h"
@@ -30,7 +31,6 @@ PSet script. See notes in EventProcessor.cpp for details about it.
3031
3132#include " TError.h"
3233
33- #include " boost/program_options.hpp"
3434#include " oneapi/tbb/task_arena.h"
3535
3636#include < cstring>
@@ -41,24 +41,6 @@ PSet script. See notes in EventProcessor.cpp for details about it.
4141#include < string>
4242#include < vector>
4343
44- // Command line parameters
45- static char const * const kParameterSetOpt = " parameter-set" ;
46- static char const * const kPythonOpt = " pythonOptions" ;
47- static char const * const kParameterSetCommandOpt = " parameter-set,p" ;
48- static char const * const kJobreportCommandOpt = " jobreport,j" ;
49- static char const * const kJobreportOpt = " jobreport" ;
50- static char const * const kEnableJobreportCommandOpt = " enablejobreport,e" ;
51- static const char * const kEnableJobreportOpt = " enablejobreport" ;
52- static char const * const kJobModeCommandOpt = " mode,m" ;
53- static char const * const kJobModeOpt = " mode" ;
54- static char const * const kNumberOfThreadsCommandOpt = " numThreads,n" ;
55- static char const * const kNumberOfThreadsOpt = " numThreads" ;
56- static char const * const kSizeOfStackForThreadCommandOpt = " sizeOfStackForThreadsInKB,s" ;
57- static char const * const kSizeOfStackForThreadOpt = " sizeOfStackForThreadsInKB" ;
58- static char const * const kHelpOpt = " help" ;
59- static char const * const kHelpCommandOpt = " help,h" ;
60- static char const * const kStrictOpt = " strict" ;
61-
6244// -----------------------------------------------
6345namespace {
6446 class EventProcessorWithSentry {
@@ -101,10 +83,9 @@ namespace {
10183 private:
10284 edm::EventProcessor* ep_;
10385 };
104-
10586} // namespace
10687
107- int main (int argc, char * argv[]) {
88+ int main (int argc, const char * argv[]) {
10889 edm::TimingServiceBase::jobStarted ();
10990
11091 int returnCode = 0 ;
@@ -116,7 +97,7 @@ int main(int argc, char* argv[]) {
11697 edm::s_defaultSizeOfStackForThreadsInKB * 1024 );
11798 std::shared_ptr<edm::Presence> theMessageServicePresence;
11899 std::unique_ptr<std::ofstream> jobReportStreamPtr;
119- std::shared_ptr<edm::serviceregistry::ServiceWrapper<edm::JobReport> > jobRep;
100+ std::shared_ptr<edm::serviceregistry::ServiceWrapper<edm::JobReport>> jobRep;
120101 EventProcessorWithSentry proc;
121102
122103 try {
@@ -145,74 +126,39 @@ int main(int argc, char* argv[]) {
145126 std::shared_ptr<edm::Presence>(edm::PresenceFactory::get ()->makePresence (" SingleThreadMSPresence" ).release ());
146127
147128 context = " Processing command line arguments" ;
148- std::string descString (argv[0 ]);
149- descString += " [options] [--" ;
150- descString += kParameterSetOpt ;
151- descString += " ] config_file \n Allowed options" ;
152- boost::program_options::options_description desc (descString);
153-
154- // clang-format off
155- desc.add_options ()(kHelpCommandOpt , " produce help message" )(
156- kParameterSetCommandOpt , boost::program_options::value<std::string>(), " configuration file" )(
157- kJobreportCommandOpt ,
158- boost::program_options::value<std::string>(),
159- " file name to use for a job report file: default extension is .xml" )(
160- kEnableJobreportCommandOpt , " enable job report files (if any) specified in configuration file" )(
161- kJobModeCommandOpt ,
162- boost::program_options::value<std::string>(),
163- " Job Mode for MessageLogger defaults - default mode is grid" )(
164- kNumberOfThreadsCommandOpt ,
165- boost::program_options::value<unsigned int >(),
166- " Number of threads to use in job (0 is use all CPUs)" )(
167- kSizeOfStackForThreadCommandOpt ,
168- boost::program_options::value<unsigned int >(),
169- " Size of stack in KB to use for extra threads (0 is use system default size)" )(kStrictOpt , " strict parsing" );
170- // clang-format on
171-
172- // anything at the end will be ignored, and sent to python
173- boost::program_options::positional_options_description p;
174- p.add (kParameterSetOpt , 1 ).add (kPythonOpt , -1 );
175-
176- // This --fwk option is not used anymore, but I'm leaving it around as
177- // it might be useful again in the future for code development
178- // purposes. We originally used it when implementing the boost
179- // state machine code.
180- boost::program_options::options_description hidden (" hidden options" );
181- hidden.add_options ()(" fwk" , " For use only by Framework Developers" )(
182- kPythonOpt ,
183- boost::program_options::value<std::vector<std::string> >(),
184- " options at the end to be passed to python" );
185-
186- boost::program_options::options_description all_options (" All Options" );
187- all_options.add (desc).add (hidden);
188-
189- boost::program_options::variables_map vm;
190- try {
191- store (boost::program_options::command_line_parser (argc, argv).options (all_options).positional (p).run (), vm);
192- notify (vm);
193- } catch (boost::program_options::error const & iException) {
194- edm::LogAbsolute (" CommandLineProcessing" )
195- << " cmsRun: Error while trying to process command line arguments:\n "
196- << iException.what () << " \n For usage and an options list, please do 'cmsRun --help'." ;
197- return edm::errors::CommandLineProcessing;
198- }
199-
200- if (vm.count (kHelpOpt )) {
201- std::cout << desc << std::endl;
202- if (!vm.count (kParameterSetOpt ))
129+ edm::CmsRunParser parser (argv[0 ]);
130+
131+ const auto & parserOutput = parser.parse (argc, argv);
132+ // return with exit code from parser
133+ if (edm::CmsRunParser::hasExit (parserOutput))
134+ return edm::CmsRunParser::getExit (parserOutput);
135+ auto vm = edm::CmsRunParser::getVM (parserOutput);
136+
137+ std::string cmdString;
138+ std::string fileName;
139+ if (vm.count (edm::CmsRunParser::kCmdOpt )) {
140+ cmdString = vm[edm::CmsRunParser::kCmdOpt ].as <std::string>();
141+ if (vm.count (edm::CmsRunParser::kParameterSetOpt )) {
142+ edm::LogAbsolute (" CommandLineProcessing" ) << " cmsRun: Error while trying to process command line arguments:\n "
143+ << " cannot use '-c [command line input]' with 'config_file'\n "
144+ << " For usage and an options list, please do 'cmsRun --help'." ;
203145 edm::HaltMessageLogging ();
204- return 0 ;
205- }
206-
207- if (!vm.count (kParameterSetOpt )) {
146+ return edm::errors::CommandLineProcessing;
147+ }
148+ } else if (!vm.count (edm::CmsRunParser::kParameterSetOpt )) {
208149 edm::LogAbsolute (" ConfigFileNotFound" ) << " cmsRun: No configuration file given.\n "
209150 << " For usage and an options list, please do 'cmsRun --help'." ;
210151 edm::HaltMessageLogging ();
211152 return edm::errors::ConfigFileNotFound;
153+ } else
154+ fileName = vm[edm::CmsRunParser::kParameterSetOpt ].as <std::string>();
155+ std::vector<std::string> pythonOptValues;
156+ if (vm.count (edm::CmsRunParser::kPythonOpt )) {
157+ pythonOptValues = vm[edm::CmsRunParser::kPythonOpt ].as <std::vector<std::string>>();
212158 }
213- std::string fileName (vm[ kParameterSetOpt ]. as <std::string>() );
159+ pythonOptValues. insert (pythonOptValues. begin (), fileName );
214160
215- if (vm.count (kStrictOpt )) {
161+ if (vm.count (edm::CmsRunParser:: kStrictOpt )) {
216162 // edm::setStrictParsing(true);
217163 edm::LogSystem (" CommandLineProcessing" ) << " Strict configuration processing is now done from python" ;
218164 }
@@ -221,9 +167,9 @@ int main(int argc, char* argv[]) {
221167 // Decide whether to enable creation of job report xml file
222168 // We do this first so any errors will be reported
223169 std::string jobReportFile;
224- if (vm.count (kJobreportOpt )) {
225- jobReportFile = vm[kJobreportOpt ].as <std::string>();
226- } else if (vm.count (kEnableJobreportOpt )) {
170+ if (vm.count (edm::CmsRunParser:: kJobreportOpt )) {
171+ jobReportFile = vm[edm::CmsRunParser:: kJobreportOpt ].as <std::string>();
172+ } else if (vm.count (edm::CmsRunParser:: kEnableJobreportOpt )) {
227173 jobReportFile = " FrameworkJobReport.xml" ;
228174 }
229175 jobReportStreamPtr = jobReportFile.empty () ? nullptr : std::make_unique<std::ofstream>(jobReportFile.c_str ());
@@ -234,15 +180,32 @@ int main(int argc, char* argv[]) {
234180 jobRep.reset (new edm::serviceregistry::ServiceWrapper<edm::JobReport>(std::move (jobRepPtr)));
235181 edm::ServiceToken jobReportToken = edm::ServiceRegistry::createContaining (jobRep);
236182
237- context = " Processing the python configuration file named " ;
238- context += fileName;
183+ if (!fileName.empty ()) {
184+ context = " Processing the python configuration file named " ;
185+ context += fileName;
186+ } else {
187+ context = " Processing the python configuration from command line " ;
188+ context += cmdString;
189+ }
239190 std::shared_ptr<edm::ProcessDesc> processDesc;
240191 try {
241- std::unique_ptr<edm::ParameterSet> parameterSet = edm::readConfig (fileName, argc, argv);
242- processDesc.reset (new edm::ProcessDesc (std::move (parameterSet)));
192+ std::unique_ptr<edm::ParameterSet> parameterSet;
193+ if (!fileName.empty ())
194+ parameterSet = edm::readConfig (fileName, pythonOptValues);
195+ else
196+ edm::makeParameterSets (cmdString, parameterSet);
197+ processDesc = std::make_shared<edm::ProcessDesc>(std::move (parameterSet));
243198 } catch (edm::Exception const &) {
244199 throw ;
245200 } catch (cms::Exception& iException) {
201+ // check for "SystemExit: 0" on second line
202+ const std::string& sysexit0 (" SystemExit: 0" );
203+ const auto & msg = iException.message ();
204+ size_t pos2 = msg.find (' \n ' );
205+ if (pos2 != std::string::npos and (msg.size () - (pos2 + 1 )) > sysexit0.size () and
206+ msg.compare (pos2 + 1 , sysexit0.size (), sysexit0) == 0 )
207+ return 0 ;
208+
246209 edm::Exception e (edm::errors::ConfigFileReadError, " " , iException);
247210 throw e;
248211 }
@@ -264,11 +227,11 @@ int main(int argc, char* argv[]) {
264227 auto threadsInfo = threadOptions (*pset);
265228
266229 // check the command line options
267- if (vm.count (kNumberOfThreadsOpt )) {
268- threadsInfo.nThreads_ = vm[kNumberOfThreadsOpt ].as <unsigned int >();
230+ if (vm.count (edm::CmsRunParser:: kNumberOfThreadsOpt )) {
231+ threadsInfo.nThreads_ = vm[edm::CmsRunParser:: kNumberOfThreadsOpt ].as <unsigned int >();
269232 }
270- if (vm.count (kSizeOfStackForThreadOpt )) {
271- threadsInfo.stackSize_ = vm[kSizeOfStackForThreadOpt ].as <unsigned int >();
233+ if (vm.count (edm::CmsRunParser:: kSizeOfStackForThreadOpt )) {
234+ threadsInfo.stackSize_ = vm[edm::CmsRunParser:: kSizeOfStackForThreadOpt ].as <unsigned int >();
272235 }
273236
274237 // if needed, re-initialise TBB
@@ -290,8 +253,8 @@ int main(int argc, char* argv[]) {
290253
291254 context = " Setting MessageLogger defaults" ;
292255 // Decide what mode of hardcoded MessageLogger defaults to use
293- if (vm.count (kJobModeOpt )) {
294- std::string jobMode = vm[kJobModeOpt ].as <std::string>();
256+ if (vm.count (edm::CmsRunParser:: kJobModeOpt )) {
257+ std::string jobMode = vm[edm::CmsRunParser:: kJobModeOpt ].as <std::string>();
295258 edm::MessageDrop::instance ()->jobMode = jobMode;
296259 }
297260
0 commit comments