Boost C++ Libraries: Ticket #4512: [program_options]: wrong option_description returned by options_descriptions::find_nothrow https://svn.boost.org/trac10/ticket/4512 <p> In 1.43 my code started failing when an option_description has two options where option1 is "all" and option2 is "all-chroots". </p> <p> I am using command_line_style::allow_guessing and at some point the command_line_parser calls options_description::find_nothrow("all",true,...) in options_description.cpp </p> <p> It turns out find_nothrow has changed since the earlier version (1.38) which I am currently using. The old version immediately returned on a full_match: </p> <pre class="wiki">... // If we have a full patch, and an approximate match, // ignore approximate match instead of reporting error. // Say, if we have options "all" and "all-chroots", then // "--all" on the command line should select the first one, // without ambiguity. // // For now, we don't check the situation when there are // two full matches. if (r == option_description::full_match) { return m_options[i].get(); } ... </pre><p> But in 1.43, the loop that iterates <code>m_options</code> sets a variable <code>found</code> to which ever match is found last, be that a full_match or an approximate_match: </p> <pre class="wiki">... if (r == option_description::full_match) { full_matches.push_back(m_options[i]-&gt;key(name)); } else { // FIXME: the use of 'key' here might not // be the best approach. approximate_matches.push_back(m_options[i]-&gt;key(name)); } found = m_options[i]; ... </pre><p> Ultimately, the variable <code>found</code> is returned and in my case with the partial match even though there really was a full match. </p> <p> I propose the following implementation of find_nothrow(...). The error checking is unchanged from 1.43 version, but a full_match, if any, will be returned as expected. </p> <pre class="wiki">const option_description* options_description::find_nothrow(const std::string&amp; name, bool approx, bool long_ignore_case, bool short_ignore_case) const { int found = -1; vector&lt;string&gt; approximate_matches; vector&lt;string&gt; full_matches; // We use linear search because matching specified option // name with the declaraed option name need to take care about // case sensitivity and trailing '*' and so we can't use simple map. for(unsigned i = 0; i &lt; m_options.size(); ++i) { option_description::match_result r = m_options[i]-&gt;match(name, approx, long_ignore_case, short_ignore_case); if (r == option_description::no_match) continue; if (r == option_description::full_match) { full_matches.push_back(m_options[i]-&gt;key(name)); // Use this full match regardless of other matches found. found = i; } else { // FIXME: the use of 'key' here might not // be the best approach. approximate_matches.push_back(m_options[i]-&gt;key(name)); // If this is the first match found the use it. If // a later full match is found that will be used instead. if (found == -1) found = i; } } if (full_matches.size() &gt; 1) boost::throw_exception( ambiguous_option(name, full_matches)); if (full_matches.empty() &amp;&amp; approximate_matches.size() &gt; 1) boost::throw_exception( ambiguous_option(name, approximate_matches)); return found&gt;=0 ? m_options[found].get() : 0; } </pre><p> I have attached my modified version of options_description.cpp </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/4512 Trac 1.4.3 Soren Soe <soren.soe@…> Thu, 05 Aug 2010 22:19:44 GMT attachment set https://svn.boost.org/trac10/ticket/4512 https://svn.boost.org/trac10/ticket/4512 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">options_description.cpp</span> </li> </ul> Ticket Vladimir Prus Fri, 06 Aug 2010 04:36:09 GMT <link>https://svn.boost.org/trac10/ticket/4512#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4512#comment:1</guid> <description> <p> Could you please try trunk or just published 1.44 beta? This issue should be fixed there. </p> </description> <category>Ticket</category> </item> <item> <author>Soren Soe <soren.soe@…></author> <pubDate>Fri, 06 Aug 2010 15:18:37 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4512#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4512#comment:2</guid> <description> <p> Yep, that fixes it. Thank you. </p> <p> Soren </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Vladimir Prus</dc:creator> <pubDate>Fri, 06 Aug 2010 15:38:29 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/4512#comment:3 https://svn.boost.org/trac10/ticket/4512#comment:3 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> Ticket