    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Using Clara to Parse Command Lines in C++</title>
        <link>https://members.accu.org/index.php/articles/2211</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 28, #1 - March 2016</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c359/">281</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-359/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+359/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Using Clara to Parse Command Lines in C++</h1>
<p><strong>Author:</strong>&nbsp;Martin Moene</p>
<p>
<strong>Date:</strong> 07 March 2016 20:26:35 +00:00 or Mon, 07 March 2016 20:26:35 +00:00</p>
<p><strong>Summary:</strong>&nbsp;Malcolm Noyes demonstrates how to get up and running.</p>
<p><strong>Body:</strong>&nbsp;<p>Recently I needed a command line parser. Previously I have used Boost.ProgramOptions which has some nice features but this wasnâ€™t available in the build of Boost libraries I was using. I needed something simple and preferably header only. Some of you may know that Iâ€™m a bit of fan of Phil Nashâ€™s Catch as a C++ unit testing framework; Catch uses Clara internally to do the command line parsing, so I thought Iâ€™d give that a try...what follows is a brief description of the basic features, which hopefully will fill a few holes in the documentation!</p>

<h2>Help!</h2>

<p>Listing 1 shows a simple program that Iâ€™ll use to demonstrate some features of Clara.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#define CLARA_CONFIG_MAIN
#include &lt;clara.h&gt;
#include &lt;iostream&gt;

struct ArticleOptions {
  ArticleOptions() : showHelp(false), 
     send(false) {}
  std::string processName;
  bool showHelp;
  bool send;
  std::string reviewer;
};
int main(int argc, char* argv[])
{
  using namespace Clara;
  CommandLine&lt;ArticleOptions&gt; cli;
  cli.bindProcessName
    (&amp;ArticleOptions::processName);
  cli[&quot;-?&quot;][&quot;-h&quot;][&quot;--help&quot;]
    .describe(&quot;describes how to use the program&quot;)
    .bind(&amp;ArticleOptions::showHelp);
  cli[&quot;-s&quot;][&quot;--send&quot;]
    .describe(&quot;should the article be sent?&quot;)
    .bind(&amp;ArticleOptions::send);
  cli[&quot;-r&quot;][&quot;--reviewer&quot;]
    .describe(&quot;who should review it?&quot;)
    .bind(&amp;ArticleOptions::reviewer,
       &quot;who to send to&quot;);
  ArticleOptions opt;
  cli.parseInto(argc,
     const_cast&lt;const char**&gt;(argv), opt);
  if (opt.showHelp) {
    cli.usage(std::cout, opt.processName);
  }
  else {
    if (opt.send) {
      std::cout 
        &lt;&lt; &quot;Send article for review by...&quot; 
        &lt;&lt; opt.reviewer 
        &lt;&lt; std::endl;
  }
  }
  return 0;
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<p>This example has three options. The first is to output help text and is introduced with <code>cli[&quot;-?&quot;][&quot;-h&quot;][&quot;--help&quot;]</code>. This tells Clara that there are three ways to request help, two short options (<code>-?</code> and <code>-h</code>) and one long one (<code>--help</code>). If we run that we get something like this:</p>

<pre class="programlisting">
  c:\Projects\ClaraExample\Debug&gt;ClaraExample -h
  usage:
    ClaraExample  [options]
  where options are:
    -?, -h, --help describes how to use the program
    -s, --send     should the article be sent?
    -r, --reviewer &lt;who to send to&gt;  
                   who should review it?</pre>

<p>The help text gives us the options defined, along with the description that we supply to the <code>describe</code> clause. For an option with no additional arguments (<code>-s</code>) this is all we get, but for an option that requires input, we get the option together with the â€˜placeholderâ€™ text that we specified in the <code>bind</code> clause.</p>

<p>For the option with no arguments, I have â€˜boundâ€™ this option to the <code>ArticleOptions</code> bool member variable <code>send</code>. If I set this option, Clara will set the member variable...nice and simple.</p>

<p>The option that requires an argument I have bound to a string. If the argument is set then the member variable will take the value of the input. Letâ€™s see how that works:</p>

<pre class="programlisting">
  c:\Projects\ClaraExample\Debug&gt;ClaraExample -sr
  &quot;Phil Nash&quot;
  Send article for review by...Phil Nash</pre>

<p>There are several ways to specify the input to an option that requires one; all these achieve the same result:</p>

<pre class="programlisting">
  ClaraExample -s -r=&quot;Phil Nash&quot;
  ClaraExample -s -r:&quot;Phil Nash&quot;
  ClaraExample -s --reviewer &quot;Phil Nash&quot;</pre>

<h2>Did I ask for that?</h2>

<p>Often I found that I wanted to know if a particular option was set and take some action based on that. Also, I wanted some default value to be set if the option wasnâ€™t set. It seems the best way to do that is to bind the option to a function (for example, see Listing 2).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
struct ArticleOptions {
    ArticleOptions() : showHelp(false)
       , send(false)
       , reviewer(&quot;Steve Love&quot;)
    {}
    // ... as before ... 
    bool send;
    std::string reviewer;

    void reviewerOptionSet(const std::string&amp; v){
      send = true;
      reviewer = v;
    }
};

int main(int argc, char* argv[])
{
  //... as before ...
  cli[&quot;-r&quot;][&quot;--reviewer&quot;]
    .describe(&quot;who should review it?&quot;)
    .bind(&amp;ArticleOptions::reviewerOptionSet
       , &quot;who to send to&quot;);

  //... as before ...
  if (opt.send) {
    std::cout &lt;&lt; &quot;Send article for review by...&quot;
    &lt;&lt; opt.reviewer &lt;&lt; std::endl;
  }
  else {
    std::cout &lt;&lt; &quot;Option not set...review by...&quot;
    &lt;&lt; opt.reviewer &lt;&lt; std::endl;
  }
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<p>This tells Clara to call the function if the option is set; the called function can do what it likes so in this case I can set both the flag and the value. If the flag is not set, then I use the default initialisation of the member variable. So now we have:</p>

<pre class="programlisting">
  c:\Projects\ClaraExample\Debug&gt;ClaraExample
  Option not set...review by...Steve Love

  c:\Projects\ClaraExample\Debug&gt;ClaraExample 
  --reviewer &quot;Phil Nash&quot;
  Send article for review by...Phil Nash</pre>

<h3>Positional arguments</h3>

<p>If your program requires more than one argument, you can do that too. First, you can bind the option to a specific position, as in Listing 3.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
//...
cli[1]
  .describe(&quot;other reviewer&quot;)
  .bind(&amp;ArticleOptions::other, 
    &quot;other reviewer&quot;);
cli[2]
  .describe(&quot;another reviewer&quot;)
  .bind(&amp;ArticleOptions::another, 
    &quot;another reviewer&quot;);

//...
  std::cout &lt;&lt; &quot;Option not set...review by...&quot; 
    &lt;&lt; opt.reviewer &lt;&lt; &quot;, &quot; &lt;&lt; opt.other &lt;&lt; &quot;, &quot; 
    &lt;&lt; opt.another &lt;&lt; std::endl;
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 3</td>
	</tr>
</table>

<pre class="programlisting">
  c:\Projects\ClaraExample\Debug&gt;ClaraExample 
  &quot;Phil Nash&quot;
  Option not set...review by...Steve Love, 
  Phil Nash,

  c:\Projects\ClaraExample\Debug&gt;ClaraExample 
  &quot;Phil Nash&quot; &quot;Roger Orr&quot;
  Option not set...review by...Steve Love, Phil
  Nash, Roger Orr</pre>

<p>Note that these are not bound to a specific named option, so we still specify an option if we want to:</p>

<pre class="programlisting">
  c:\Projects\ClaraExample\Debug&gt;ClaraExample 
  &quot;Phil Nash&quot; -r &quot;You know who&quot; &quot;Roger Orr&quot;
  Send article for review by...You know who, 
  Phil Nash, Roger Orr</pre>
<p>On the other hand, if you donâ€™t care where an option should appear, the option can be bound to an â€˜unpositionalâ€™ variable, as in Listing 4.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
struct ArticleOptions {
  //...
  std::string omnificent;
};

  //...
  cli[_]
    .describe(&quot;if all else fails&quot;)
    .bind(&amp;ArticleOptions::omnificent, 
      &quot;seek help from above&quot;);

  // ...
  std::cout &lt;&lt; &quot;If that fails, review by...&quot; 
            &lt;&lt; opt.omnificent &lt;&lt; std::endl;
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 4</td>
	</tr>
</table>

<pre class="programlisting">
  c:\Projects\ClaraExample\Debug&gt;ClaraExample 
  &quot;Phil Nash&quot; &quot;Roger Orr&quot; -r &quot;You know who&quot; God
  If that fails, review by...God</pre>

<h3>Bah humbug...but Iâ€™m lazy...canâ€™t Clara figure that out?</h3>

<p>One thing I would like to see is that Clara could do the test for whether an option was set; after all, Clara â€˜knowsâ€™ whether the option was set since it either parse it or it didnâ€™t. That would save me having to have a flag for each option and possibly could be tested with something like:</p>

<pre class="programlisting">
  if(cli['-r'].wasSet()) {
    ...
  }</pre>
  
<p>That would mean I wouldnâ€™t need to bind to a function that sets a flag and a value; instead I could just bind to the member. The lookup for the option would take longer than just testing the flag but I doubt if testing command line options is a time killer for most applications.</p>

<p>The other thing that Iâ€™d like is for the â€˜placeholderâ€™ text to be the default value, even if the option is not set. Then I wouldnâ€™t need to initialise the member in the struct, I can do it in the bind, which would improve the locality of the information associated with the option, something like Listing 5</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
struct Opt
{
  std::string value;
};
//...
cli[&quot;-v&quot;]
  .bind(&amp;Opt::value, 
    &quot;this is the default value&quot;);
//...
if(opt.wasSet(&quot;-v&quot;)) {
  std::cout &lt;&lt; &quot;Value set: &quot; &lt;&lt; opt.value 
            &lt;&lt; std::endl;
} else {
  std::cout &lt;&lt; &quot;Not set: &quot; &lt;&lt; opt.value 
            &lt;&lt; std::endl;
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 5</td>
	</tr>
</table>

<p>which would be used like this:</p>

<pre class="programlisting">
  c:\Projects\ClaraExample\Debug&gt;ClaraExample 
  -v &quot;Option overide&quot;
  Value set: Option override

  c:\Projects\ClaraExample\Debug&gt;ClaraExample
  Not set: this is the default value</pre>
  
<p>Iâ€™ll have to ask Phil if he thinks either of those is a good idea...</p>

<h2>Summary</h2>

<p>Clara is very simple to get going; just download the header (1). It is header only, so thereâ€™s no linking to incompatible libraries. What it does, it does very well and what it does less well can be worked around very easily. In short, it solved my problem, so Iâ€™m (mostly) happy!</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
