Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/Control/Inciter/CmdLine/Parser.cpp
4 : : \copyright 2012-2015 J. Bakosi,
5 : : 2016-2018 Los Alamos National Security, LLC.,
6 : : 2019-2021 Triad National Security, LLC.
7 : : All rights reserved. See the LICENSE file for details.
8 : : \brief Inciter's command line parser
9 : : \details This file defines the command-line argument parser for the
10 : : computational shock hydrodynamics tool, Inciter.
11 : : */
12 : : // *****************************************************************************
13 : :
14 : : #include "NoWarning/pegtl.hpp"
15 : : #include "NoWarning/charm.hpp"
16 : :
17 : : #include "QuinoaConfig.hpp"
18 : : #include "Exception.hpp"
19 : : #include "Print.hpp"
20 : : #include "Keywords.hpp"
21 : : #include "Inciter/Types.hpp"
22 : : #include "Inciter/CmdLine/Parser.hpp"
23 : : #include "Inciter/CmdLine/Grammar.hpp"
24 : : #include "Inciter/CmdLine/CmdLine.hpp"
25 : : #include "Inciter/InputDeck/InputDeck.hpp"
26 : :
27 : : namespace tk {
28 : : namespace grm {
29 : :
30 : : tk::Print g_print;
31 : :
32 : : } // grm::
33 : : } // tk::
34 : :
35 : : namespace inciter {
36 : :
37 : : extern ctr::InputDeck g_inputdeck;
38 : :
39 : : } // inciter::
40 : :
41 : : using inciter::CmdLineParser;
42 : :
43 : 233 : CmdLineParser::CmdLineParser( int argc, char** argv,
44 : : const tk::Print& print,
45 : 233 : ctr::CmdLine& cmdline ) :
46 : 233 : StringParser( argc, argv )
47 : : // *****************************************************************************
48 : : // Contructor: parse the command line for Inciter
49 : : //! \param[in] argc Number of C-style character arrays in argv
50 : : //! \param[in] argv C-style character array of character arrays
51 : : //! \param[in] print Pretty printer
52 : : //! \param[in,out] cmdline Command-line stack where data is stored from parsing
53 : : // *****************************************************************************
54 : : {
55 : : // Create CmdLine (a tagged tuple) to store parsed input
56 [ + - ][ + - ]: 466 : ctr::CmdLine cmd( g_inputdeck.get< tag::cmd, tag::ctrinfo >() );
57 : :
58 : : // Reset parser's output stream to that of print's. This is so that mild
59 : : // warnings emitted during parsing can be output using the pretty printer.
60 : : // Usually, errors and warnings are simply accumulated during parsing and
61 : : // printed during diagnostics after the parser has finished. However, in some
62 : : // special cases we can provide a more user-friendly message right during
63 : : // parsing since there is more information available to construct a more
64 : : // sensible message. This is done in e.g., tk::grm::store_option. Resetting
65 : : // the global g_print, to that of passed in as the constructor argument allows
66 : : // not to have to create a new pretty printer, but use the existing one.
67 [ + - ][ + - ]: 233 : tk::grm::g_print.reset( print.save() );
68 : :
69 : : // Parse command line string by populating the underlying tagged tuple:
70 [ + - ]: 466 : tao::pegtl::memory_input<> in( m_string, "command line" );
71 [ + - ]: 233 : tao::pegtl::parse< cmd::read_string, tk::grm::action >( in, cmd );
72 : :
73 : : // Echo errors and warnings accumulated during parsing
74 [ + - ]: 233 : diagnostics( print, cmd.get< tag::error >() );
75 : :
76 : : // Strip command line (and its underlying tagged tuple) from PEGTL instruments
77 : : // and transfer it out
78 : 233 : cmdline = std::move( cmd );
79 : :
80 : : // If we got here, the parser succeeded
81 [ + - ][ + - ]: 233 : print.item( "Parsed command line", "success" );
82 : :
83 : : // Print out help on all command-line arguments if the executable was invoked
84 : : // without arguments or the help was requested
85 : 233 : const auto helpcmd = cmdline.get< tag::help >();
86 [ + - ][ - + ]: 233 : if (argc == 1 || helpcmd) {
87 [ - - ][ - - ]: 0 : print.help< tk::QUIET >( tk::inciter_executable(),
[ - - ][ - - ]
88 : 0 : cmdline.get< tag::cmdinfo >(),
89 : : "Command-line Parameters:", "-" );
90 [ - - ]: 0 : print.mandatory< tk::QUIET >(
91 [ - - ][ - - ]: 0 : "The '--" + kw::input().string() + " <filename>' and the "
[ - - ]
92 [ - - ][ - - ]: 0 : "'--" + kw::control().string() + " <filename>' arguments are mandatory." );
[ - - ]
93 [ - - ][ - - ]: 0 : print.usage< tk::QUIET >(
94 [ - - ]: 0 : tk::inciter_executable(),
95 [ - - ][ - - ]: 0 : "charmrun +p4 " + tk::inciter_executable() + " -" +
[ - - ][ - - ]
[ - - ]
96 [ - - ][ - - ]: 0 : *kw::verbose().alias() + " -" + *kw::control().alias() +
[ - - ][ - - ]
97 [ - - ][ - - ]: 0 : " vort.q -" + *kw::input().alias() + " unitcube.exo",
[ - - ]
98 : : "will execute the simulation configured in the control file 'vort.q' "
99 : : "using the mesh in 'unitcube.exo' on 4 CPUs producing verbose screen "
100 : : "output" );
101 : : }
102 : :
103 : : // Print out help on all control file keywords if they were requested
104 : 233 : const auto helpctr = cmdline.get< tag::helpctr >();
105 [ - + ]: 233 : if (helpctr)
106 [ - - ][ - - ]: 0 : print.help< tk::QUIET >( tk::inciter_executable(),
[ - - ][ - - ]
107 : 0 : cmdline.get< tag::ctrinfo >(),
108 : : "Control File Keywords:" );
109 : :
110 : : // Print out verbose help for a single keyword if requested
111 [ + - ]: 466 : const auto helpkw = cmdline.get< tag::helpkw >();
112 [ - + ]: 233 : if (!helpkw.keyword.empty())
113 [ - - ][ - - ]: 0 : print.helpkw< tk::QUIET >( tk::inciter_executable(), helpkw );
114 : :
115 : : // Print out version information if it was requested
116 : 233 : const auto version = cmdline.get< tag::version >();
117 [ - + ]: 233 : if (version)
118 [ - - ][ - - ]: 0 : print.version< tk::QUIET >( tk::inciter_executable(),
119 [ - - ]: 0 : tk::quinoa_version(),
120 [ - - ]: 0 : tk::git_commit(),
121 [ - - ]: 0 : tk::copyright() );
122 : :
123 : : // Print out license information if it was requested
124 : 233 : const auto license = cmdline.get< tag::license >();
125 [ - + ]: 233 : if (license)
126 [ - - ][ - - ]: 0 : print.license< tk::QUIET >( tk::inciter_executable(), tk::license() );
[ - - ]
127 : :
128 : : // Immediately exit if any help was output or was called without any argument
129 : : // or version or license info was requested with zero exit code
130 [ + - ][ + - ]: 233 : if (argc == 1 || helpcmd || helpctr || !helpkw.keyword.empty() || version ||
[ + - ][ + - ]
[ + - ][ - + ]
[ - + ]
131 : : license)
132 : : {
133 [ - - ]: 0 : CkExit();
134 : : }
135 : :
136 : : // Make sure mandatory arguments are set
137 [ + - ]: 466 : auto ctralias = kw::control().alias();
138 [ - + ][ - - ]: 233 : ErrChk( !(cmdline.get< tag::io, tag::control >().empty()),
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
139 : : "Mandatory control file not specified. "
140 : : "Use '--" + kw::control().string() + " <filename>'" +
141 : : ( ctralias ? " or '-" + *ctralias + " <filename>'" : "" ) + '.' );
142 : 233 : }
|