Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/Control/MeshConv/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 MeshConv's command line parser
9 : : \details This file defines the command-line argument parser for the mesh
10 : : file converter, MeshConv.
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 "MeshConv/Types.hpp"
22 : : #include "MeshConv/CmdLine/Parser.hpp"
23 : : #include "MeshConv/CmdLine/Grammar.hpp"
24 : :
25 : : namespace tk {
26 : : namespace grm {
27 : :
28 : : tk::Print g_print;
29 : :
30 : : } // grm::
31 : : } // tk::
32 : :
33 : : using meshconv::CmdLineParser;
34 : :
35 : 18 : CmdLineParser::CmdLineParser( int argc,
36 : : char** argv,
37 : : const tk::Print& print,
38 : 18 : ctr::CmdLine& cmdline ) :
39 : 18 : StringParser( argc, argv )
40 : : // *****************************************************************************
41 : : // Contructor: parse the command line for MeshConv
42 : : //! \param[in] argc Number of C-style character arrays in argv
43 : : //! \param[in] argv C-style character array of character arrays
44 : : //! \param[in] print Pretty printer
45 : : //! \param[inout] cmdline Command-line stack where data is stored from parsing
46 : : // *****************************************************************************
47 : : {
48 : : // Create CmdLine (a tagged tuple) to store parsed input
49 [ + - ]: 18 : ctr::CmdLine cmd;
50 : :
51 : : // Reset parser's output stream to that of print's. This is so that mild
52 : : // warnings emitted during parsing can be output using the pretty printer.
53 : : // Usually, errors and warnings are simply accumulated during parsing and
54 : : // printed during diagnostics after the parser has finished. However, in some
55 : : // special cases we can provide a more user-friendly message right during
56 : : // parsing since there is more information available to construct a more
57 : : // sensible message. This is done in e.g., tk::grm::store_option. Resetting
58 : : // the global g_print, to that of passed in as the constructor argument allows
59 : : // not to have to create a new pretty printer, but use the existing one.
60 [ + - ]: 18 : tk::grm::g_print.reset( print.save() );
61 : :
62 : : // Parse command line string by populating the underlying tagged tuple
63 : : tao::pegtl::memory_input<> in( m_string, "command line" );
64 : : tao::pegtl::parse< cmd::read_string, tk::grm::action >( in, cmd );
65 : :
66 : : // Echo errors and warnings accumulated during parsing
67 [ + - ]: 18 : diagnostics( print, cmd.get< tag::error >() );
68 : :
69 : : // Strip command line (and its underlying tagged tuple) from PEGTL instruments
70 : : // and transfer it out
71 : : cmdline = std::move( cmd );
72 : :
73 : : // If we got here, the parser has succeeded
74 [ + - ][ + - ]: 18 : print.item("Parsed command line", "success");
75 : :
76 : : // Print out help on all command-line arguments if the executable was invoked
77 : : // without arguments or the help was requested
78 : 18 : const auto helpcmd = cmdline.get< tag::help >();
79 [ - + ]: 18 : if (argc == 1 || helpcmd) {
80 [ - - ][ - - ]: 0 : print.help< tk::QUIET >( tk::meshconv_executable(),
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
81 : : cmdline.get< tag::cmdinfo >(),
82 : : "Command-line Parameters:", "-" );
83 [ - - ]: 0 : print.mandatory< tk::QUIET >(
84 [ - - ][ - - ]: 0 : "The '--" + kw::input().string() + " <filename>' and the "
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
85 [ - - ][ - - ]: 0 : "'--" + kw::output().string() + " <filename>' arguments are mandatory." );
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
86 [ - - ][ - - ]: 0 : print.usage< tk::QUIET >(
87 [ - - ][ - - ]: 0 : tk::meshconv_executable(),
[ - - ]
88 [ - - ][ - - ]: 0 : tk::meshconv_executable() + " -" + *kw::input().alias() + " in.msh -" +
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
89 [ - - ][ - - ]: 0 : *kw::output().alias() + " out.exo",
[ - - ]
90 : : "will read data from 'in.msh' (in Gmsh format) and output it to "
91 : : "out.exo' (in ExodusII format)" );
92 : : }
93 : :
94 : : // Print out verbose help for a single keyword if requested
95 [ + - ]: 36 : const auto helpkw = cmdline.get< tag::helpkw >();
96 [ - + ]: 18 : if (!helpkw.keyword.empty())
97 [ - - ][ - - ]: 0 : print.helpkw< tk::QUIET >( tk::meshconv_executable(), helpkw );
98 : :
99 : : // Print out version information if it was requested
100 : 18 : const auto version = cmdline.get< tag::version >();
101 [ - + ]: 18 : if (version)
102 [ - - ][ - - ]: 0 : print.version< tk::QUIET >( tk::meshconv_executable(),
[ - - ][ - - ]
103 [ - - ][ - - ]: 0 : tk::quinoa_version(),
[ - - ]
104 [ - - ][ - - ]: 0 : tk::git_commit(),
[ - - ]
105 [ - - ]: 0 : tk::copyright() );
106 : :
107 : : // Print out license information if it was requested
108 : 18 : const auto license = cmdline.get< tag::license >();
109 [ - + ]: 18 : if (license)
110 [ - - ][ - - ]: 0 : print.license< tk::QUIET >( tk::meshconv_executable(), tk::license() );
[ - - ][ - - ]
[ - - ]
111 : :
112 : : // Immediately exit if any help was output or was called without any argument
113 : : // or version or license info was requested with zero exit code
114 [ + - ][ + - ]: 18 : if (argc == 1 || helpcmd || !helpkw.keyword.empty() || version || license)
[ - + ]
115 [ - - ]: 0 : CkExit();
116 : :
117 : : // Make sure mandatory arguments are set
118 [ + - ]: 18 : auto ialias = kw::input().alias();
119 [ + - ][ - + ]: 36 : auto oalias = kw::output().alias();
120 [ - + ][ - - ]: 18 : ErrChk( !(cmdline.get< tag::io, tag::input >().empty()),
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
121 : : "Mandatory input file not specified. "
122 : : "Use '--" + kw::input().string() + " <filename>'" +
123 : : ( ialias ? " or '-" + *ialias + " <filename>'" : "" ) + '.' );
124 [ - + ][ - - ]: 18 : ErrChk( !(cmdline.get< tag::io, tag::output >().empty()),
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ][ - - ]
[ - - ]
125 : : "Mandatory output file not specified. "
126 : : "Use '--" + kw::output().string() + " <filename>'" +
127 : : ( oalias ? " or '-" + *oalias + " <filename>'" : "" ) + '.' );
128 : 18 : }
|